test(user): 점주 서비스 - 주문 페이지 테스트 추가
Todo: JWT 구현 시 storeId 및 userId 가져오는 부분 기능 리팩터링 필요 - Spring Rest Docs 를 통한 테스트 추가
This commit is contained in:
@@ -64,8 +64,11 @@
|
||||
== snippets 작성 컨벤션
|
||||
domain-httpRequestCode-etc
|
||||
|
||||
== 상품
|
||||
=== 상품 조회
|
||||
operation::item-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields']
|
||||
=== 상품 조회 (존재하지 않는 상품)
|
||||
operation::item-get-notExistItemException[snippets='curl-request,http-request,http-response,path-parameters,response-fields']
|
||||
== 주문
|
||||
=== 점주 서비스 - 주문 페이지
|
||||
- 페이지 offset : 6
|
||||
|
||||
operation::orderMain-get[snippets='curl-request,http-request,http-response,request-parameters,response-fields']
|
||||
=== 점주 서비스 - 주문 페이지 (잘못된 파라미터 형식)
|
||||
|
||||
operation::orderMain-get-badParameterException[snippets='curl-request,http-request,http-response,request-parameters,response-fields']
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.justpickup.orderservice.domain.order.dto;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.validation.constraints.Pattern;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
@Data @NoArgsConstructor @AllArgsConstructor
|
||||
public class OrderSearchCondition {
|
||||
|
||||
@Pattern(regexp = "^(19|20)\\d{2}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[0-1])$",
|
||||
message = "YYYY-MM-DD 형식에 맞게 작성되지 않았습니다.")
|
||||
private String orderDate;
|
||||
private Long lastOrderId;
|
||||
|
||||
public LocalDateTime getOrderStartTime() {
|
||||
LocalDate orderTime = LocalDate.parse(orderDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
return orderTime.atStartOfDay();
|
||||
}
|
||||
|
||||
public LocalDateTime getOrderEndTime() {
|
||||
LocalDate orderTime = LocalDate.parse(orderDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
return LocalDateTime.of(orderTime, LocalTime.of(23, 59, 59));
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,16 @@
|
||||
package com.justpickup.orderservice.domain.order.entity;
|
||||
|
||||
import com.justpickup.orderservice.domain.order.dto.OrderDto;
|
||||
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
||||
import com.justpickup.orderservice.domain.orderItem.entity.OrderItem;
|
||||
import com.justpickup.orderservice.domain.transaction.entity.Transaction;
|
||||
import com.justpickup.orderservice.global.entity.BaseEntity;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.hibernate.annotations.BatchSize;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Entity
|
||||
@Table(name = "orders")
|
||||
@@ -28,6 +26,8 @@ public class Order extends BaseEntity {
|
||||
|
||||
private Long userCouponId;
|
||||
|
||||
private Long storeId;
|
||||
|
||||
private Long orderPrice;
|
||||
|
||||
private LocalDateTime orderTime;
|
||||
@@ -40,6 +40,7 @@ public class Order extends BaseEntity {
|
||||
@OneToOne(mappedBy = "order", fetch = FetchType.LAZY)
|
||||
private Transaction transaction;
|
||||
|
||||
@BatchSize(size = 100)
|
||||
@OneToMany(mappedBy = "order")
|
||||
private List<OrderItem> orderItems;
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package com.justpickup.orderservice.domain.order.repository;
|
||||
|
||||
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
|
||||
import com.justpickup.orderservice.domain.order.entity.Order;
|
||||
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
|
||||
import static com.justpickup.orderservice.domain.order.entity.QOrder.order;
|
||||
@@ -18,18 +18,34 @@ public class OrderRepositoryCustom {
|
||||
|
||||
private final JPAQueryFactory queryFactory;
|
||||
|
||||
public List<Order> findOrderMainBetweenOrderDate(LocalDate orderDate) {
|
||||
LocalDateTime start = orderDate.atStartOfDay();
|
||||
LocalDateTime end = LocalDateTime.of(orderDate, LocalTime.of(23, 59, 59));
|
||||
/*
|
||||
SELECT *
|
||||
FROM order
|
||||
WHERE 조건문
|
||||
AND id < 마지막 조회 ID
|
||||
ORDER BY id desc
|
||||
LIMIT 페이지 사이즈
|
||||
*/
|
||||
public List<Order> findOrderMain(OrderSearchCondition condition, Long storeId) {
|
||||
LocalDateTime start = condition.getOrderStartTime();
|
||||
LocalDateTime end = condition.getOrderEndTime();
|
||||
|
||||
return queryFactory
|
||||
.selectFrom(order)
|
||||
.join(order.orderItems).fetchJoin()
|
||||
.join(order.transaction).fetchJoin()
|
||||
.where(
|
||||
order.orderTime.between(start, end)
|
||||
order.orderTime.between(start, end),
|
||||
order.storeId.eq(storeId),
|
||||
orderIdLt(condition.getLastOrderId())
|
||||
)
|
||||
.orderBy(order.orderTime.desc())
|
||||
.limit(6)
|
||||
.distinct()
|
||||
.fetch();
|
||||
}
|
||||
|
||||
private BooleanExpression orderIdLt(Long lastOrderId) {
|
||||
return lastOrderId != null ? order.id.lt(lastOrderId) : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.justpickup.orderservice.domain.order.service;
|
||||
|
||||
import com.justpickup.orderservice.domain.order.dto.OrderDto;
|
||||
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
public interface OrderService {
|
||||
List<OrderDto> findOrderMain(LocalDate localDate);
|
||||
List<OrderDto> findOrderMain(OrderSearchCondition condition, Long storeId);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package com.justpickup.orderservice.domain.order.service;
|
||||
|
||||
import com.justpickup.orderservice.domain.order.dto.OrderDto;
|
||||
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
|
||||
import com.justpickup.orderservice.domain.order.repository.OrderRepository;
|
||||
import com.justpickup.orderservice.domain.order.repository.OrderRepositoryCustom;
|
||||
import com.justpickup.orderservice.global.client.store.GetItemResponse;
|
||||
import com.justpickup.orderservice.global.client.store.StoreClient;
|
||||
import com.justpickup.orderservice.global.client.user.UserClient;
|
||||
import com.justpickup.orderservice.global.client.user.GetCustomerResponse;
|
||||
import com.justpickup.orderservice.global.client.user.UserClient;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -28,23 +28,24 @@ public class OrderServiceImpl implements OrderService {
|
||||
private final UserClient userClient;
|
||||
|
||||
@Override
|
||||
public List<OrderDto> findOrderMain(LocalDate orderDate) {
|
||||
public List<OrderDto> findOrderMain(OrderSearchCondition condition, Long storeId) {
|
||||
// 주문 가져오기
|
||||
List<OrderDto> orderDtoList = orderRepositoryCustom.findOrderMainBetweenOrderDate(orderDate)
|
||||
.stream()
|
||||
.map(OrderDto::createFullField)
|
||||
.collect(Collectors.toList());
|
||||
List<OrderDto> orderDtoList =
|
||||
orderRepositoryCustom.findOrderMain(condition, storeId)
|
||||
.stream()
|
||||
.map(OrderDto::createFullField)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 사용자명 및 아이템 이름 가져오기
|
||||
orderDtoList.forEach(orderDto -> {
|
||||
GetCustomerResponse getCustomerResponse = userClient.getUser(orderDto.getUserId())
|
||||
.getData();
|
||||
GetCustomerResponse getCustomerResponse =
|
||||
userClient.getUser(orderDto.getUserId()).getData();
|
||||
orderDto.setUserName(getCustomerResponse.getUserName());
|
||||
|
||||
orderDto.getOrderItemDtoList()
|
||||
.forEach(orderItemDto -> {
|
||||
GetItemResponse getItemResponse = storeClient.getItem(orderItemDto.getItemId())
|
||||
.getData();
|
||||
GetItemResponse getItemResponse =
|
||||
storeClient.getItem(orderItemDto.getItemId()).getData();
|
||||
orderItemDto.setItemName(getItemResponse.getName());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.justpickup.orderservice.domain.order.web;
|
||||
|
||||
import com.justpickup.orderservice.domain.order.dto.OrderDto;
|
||||
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
|
||||
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
||||
import com.justpickup.orderservice.domain.order.service.OrderService;
|
||||
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
||||
@@ -16,8 +17,6 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -30,30 +29,21 @@ public class OrderController {
|
||||
private final OrderService orderService;
|
||||
|
||||
@GetMapping("/orderMain")
|
||||
public ResponseEntity orderMain(@Valid OrderMainRequest orderMainRequest) {
|
||||
public ResponseEntity orderMain(@Valid OrderSearchCondition condition) {
|
||||
// TODO: 2022/02/04 JWT 구현 시 변경 요망
|
||||
Long userId = 1L;
|
||||
Long storeId = 1L;
|
||||
|
||||
List<OrderDto> orderDto = orderService.findOrderMain(orderMainRequest.convertOrderTimeToLocalDate());
|
||||
List<OrderDto> orderDto = orderService.findOrderMain(condition, storeId);
|
||||
|
||||
List<OrderMainResponse> orderMainResponses = orderDto.stream()
|
||||
.map(OrderMainResponse::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
return ResponseEntity.status(HttpStatus.OK)
|
||||
.body(Result.createSuccessResult(orderMainResponses));
|
||||
}
|
||||
|
||||
@Data @NoArgsConstructor @AllArgsConstructor
|
||||
static class OrderMainRequest {
|
||||
// yyyy-mm-dd 형태를 가지는 패턴 조사
|
||||
@Pattern(regexp = "^(19|20)\\d{2}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[0-1])$",
|
||||
message = "YYYY-MM-DD 형식에 맞게 작성되지 않았습니다.")
|
||||
private String orderTime;
|
||||
|
||||
public LocalDate convertOrderTimeToLocalDate() {
|
||||
return LocalDate.parse(orderTime, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
}
|
||||
}
|
||||
|
||||
@Data @NoArgsConstructor @AllArgsConstructor
|
||||
static class OrderMainResponse {
|
||||
private Long orderId;
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.justpickup.orderservice.config;
|
||||
|
||||
import org.springframework.boot.test.autoconfigure.restdocs.RestDocsMockMvcConfigurationCustomizer;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
|
||||
|
||||
@TestConfiguration
|
||||
public class TestConfig {
|
||||
|
||||
@Bean
|
||||
public RestDocsMockMvcConfigurationCustomizer restDocsMockMvcConfigurationCustomizer() {
|
||||
return configurer -> configurer.operationPreprocessors()
|
||||
.withRequestDefaults(prettyPrint())
|
||||
.withResponseDefaults(prettyPrint());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
package com.justpickup.orderservice.domain.order.web;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.justpickup.orderservice.config.TestConfig;
|
||||
import com.justpickup.orderservice.domain.order.dto.OrderDto;
|
||||
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
|
||||
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
||||
import com.justpickup.orderservice.domain.order.service.OrderService;
|
||||
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
||||
import com.justpickup.orderservice.global.dto.Code;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.restdocs.request.RequestDocumentation.*;
|
||||
|
||||
@WebMvcTest(OrderController.class)
|
||||
@Import(TestConfig.class)
|
||||
@AutoConfigureRestDocs(uriHost = "127.0.0.1", uriPort = 8001)
|
||||
class OrderControllerTest {
|
||||
|
||||
@Autowired
|
||||
ObjectMapper objectMapper;
|
||||
|
||||
@Autowired
|
||||
MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
OrderService orderService;
|
||||
|
||||
@Test
|
||||
@DisplayName("점주 서비스 - 주문 페이지")
|
||||
void getOrderMain() throws Exception {
|
||||
// GIVEN
|
||||
String orderDate = "2022-02-03";
|
||||
Long lastOrderId = 7L;
|
||||
OrderSearchCondition condition = new OrderSearchCondition(orderDate, lastOrderId);
|
||||
// TODO: 2022/02/07 jwt 구현 시 변경 요망
|
||||
Long storeId = 1L;
|
||||
|
||||
given(orderService.findOrderMain(condition, storeId))
|
||||
.willReturn(getOrderMainDtoList());
|
||||
|
||||
// WHEN
|
||||
ResultActions actions = mockMvc.perform(get("/orderMain")
|
||||
.param("orderDate", orderDate)
|
||||
.param("lastOrderId", String.valueOf(lastOrderId))
|
||||
);
|
||||
|
||||
// THEN
|
||||
actions.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("code").value(Code.SUCCESS.name()))
|
||||
.andExpect(jsonPath("message").isEmpty())
|
||||
.andExpect(jsonPath("data").exists())
|
||||
.andExpect(jsonPath("data[*].orderItemResponses").exists())
|
||||
.andExpect(jsonPath("data[*].orderStatus").exists())
|
||||
.andExpect(jsonPath("data[*].orderTime").exists())
|
||||
.andDo(print())
|
||||
.andDo(document("orderMain-get",
|
||||
requestParameters(
|
||||
parameterWithName("orderDate").description("주문 날짜 YYYY-MM-DD"),
|
||||
parameterWithName("lastOrderId").optional().description("페이지의 마지막 주문 고유 번호")
|
||||
),
|
||||
responseFields(
|
||||
fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"),
|
||||
fieldWithPath("message").description("메시지"),
|
||||
fieldWithPath("data[*].orderId").description("주문 고유 번호"),
|
||||
fieldWithPath("data[*].userId").description("고객 고유 번호"),
|
||||
fieldWithPath("data[*].userName").description("고객 이름"),
|
||||
fieldWithPath("data[*].orderItemResponses[*].orderItemId").description("장바구니 고유번호"),
|
||||
fieldWithPath("data[*].orderItemResponses[*].itemId").description("상품 고유번호"),
|
||||
fieldWithPath("data[*].orderItemResponses[*].itemName").description("상품 이름"),
|
||||
fieldWithPath("data[*].orderStatus").description("주문 상태"),
|
||||
fieldWithPath("data[*].orderTime").description("주문 시간")
|
||||
)
|
||||
))
|
||||
;
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("점주 서비스 - 주문 페이지 (잘못된 파라미터 형식)")
|
||||
void getOrderMainBadRequestException() throws Exception {
|
||||
// GIVEN
|
||||
String orderDate = "20220203";
|
||||
Long lastOrderId = 7L;
|
||||
|
||||
// WHEN
|
||||
ResultActions actions = mockMvc.perform(get("/orderMain")
|
||||
.param("orderDate", orderDate)
|
||||
.param("lastOrderId", String.valueOf(lastOrderId))
|
||||
);
|
||||
|
||||
// THEN
|
||||
actions.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("code").value(Code.ERROR.name()))
|
||||
.andExpect(jsonPath("message").isNotEmpty())
|
||||
.andExpect(jsonPath("data").isEmpty())
|
||||
.andDo(print())
|
||||
.andDo(document("orderMain-get-badParameterException",
|
||||
requestParameters(
|
||||
parameterWithName("orderDate").description("주문 날짜 YYYY-MM-DD"),
|
||||
parameterWithName("lastOrderId").optional().description("페이지의 마지막 주문 고유 번호")
|
||||
),
|
||||
responseFields(
|
||||
fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"),
|
||||
fieldWithPath("message").description("메시지"),
|
||||
fieldWithPath("data").description("데이터")
|
||||
)
|
||||
)
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
private List<OrderDto> getOrderMainDtoList() {
|
||||
OrderItemDto orderItemDto_100 = OrderItemDto.builder()
|
||||
.id(100L)
|
||||
.itemId(100L)
|
||||
.build();
|
||||
orderItemDto_100.setItemName("아이템1");
|
||||
OrderItemDto orderItemDto_101 = OrderItemDto.builder()
|
||||
.id(101L)
|
||||
.itemId(101L)
|
||||
.build();
|
||||
orderItemDto_101.setItemName("아이템2");
|
||||
OrderItemDto orderItemDto_102 = OrderItemDto.builder()
|
||||
.id(102L)
|
||||
.itemId(102L)
|
||||
.build();
|
||||
orderItemDto_102.setItemName("아이템3");
|
||||
OrderItemDto orderItemDto_103 = OrderItemDto.builder()
|
||||
.id(103L)
|
||||
.itemId(103L)
|
||||
.build();
|
||||
orderItemDto_103.setItemName("아이템2");
|
||||
|
||||
OrderDto orderDto_1 = OrderDto.builder()
|
||||
.id(1L)
|
||||
.userId(1L)
|
||||
.orderItemDtoList(List.of(orderItemDto_100, orderItemDto_101))
|
||||
.orderStatus(OrderStatus.PLACED)
|
||||
.orderTime(LocalDateTime.of(2022, 2, 3, 14, 0, 0))
|
||||
.build();
|
||||
orderDto_1.setUserName("닉네임");
|
||||
OrderDto orderDto_2 = OrderDto.builder()
|
||||
.id(2L)
|
||||
.userId(1L)
|
||||
.orderItemDtoList(List.of(orderItemDto_102, orderItemDto_103))
|
||||
.orderStatus(OrderStatus.CANCELED)
|
||||
.orderTime(LocalDateTime.of(2022, 2, 3, 15, 0, 0))
|
||||
.build();
|
||||
orderDto_2.setUserName("닉네임");
|
||||
|
||||
return List.of(orderDto_1, orderDto_2);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user