diff --git a/.github/workflows/cd-prod.yml b/.github/workflows/cd-prod.yml index b49c6e5..a9067d3 100644 --- a/.github/workflows/cd-prod.yml +++ b/.github/workflows/cd-prod.yml @@ -4,6 +4,7 @@ on: workflow_run: workflows: [ "CI-PROD" ] types: [ completed ] + branches: [ main, dev ] workflow_dispatch: concurrency: @@ -29,9 +30,7 @@ jobs: github.event_name == 'workflow_dispatch' || ( github.event_name == 'workflow_run' && - github.event.workflow_run.conclusion == 'success' && - github.event.workflow_run.event == 'push' && - github.event.workflow_run.head_branch == 'main' + github.event.workflow_run.conclusion == 'success' ) runs-on: ubuntu-latest timeout-minutes: 20 diff --git a/.github/workflows/ci-prod.yml b/.github/workflows/ci-prod.yml index c220937..bd29c93 100644 --- a/.github/workflows/ci-prod.yml +++ b/.github/workflows/ci-prod.yml @@ -1,8 +1,6 @@ name: CI-PROD on: - pull_request: - branches: [ main, dev ] push: branches: [ main, dev ] @@ -37,14 +35,12 @@ jobs: run: echo "IMAGE_TAG=$(echo ${{ github.sha }} | cut -c1-7)" >> $GITHUB_ENV - name: Configure AWS credentials (OIDC) # OIDC 기반으로 역할 자격증명 - if: github.event_name == 'push' uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN }} aws-region: ${{ vars.AWS_REGION }} - name: Login to Amazon ECR # 위에서 자격증명하고 ecr 로그인 - if: github.event_name == 'push' uses: aws-actions/amazon-ecr-login@v2 - name: Build Docker image # 이미지 빌드해서 @@ -52,6 +48,5 @@ jobs: docker build --build-arg SERVER_PORT=${{ vars.SERVER_PORT }} -t ${{ vars.ECR_REGISTRY }}/${{ vars.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} . - name: Push Docker image to ECR # 이미지 ecr로 업로드 - if: github.event_name == 'push' run: | docker push ${{ vars.ECR_REGISTRY }}/${{ vars.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a0da9c0 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,31 @@ +name: CI + +on: + pull_request: + branches: [ main, dev ] + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "17" + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Grant execute permission for gradlew + run: chmod +x ./gradlew + + - name: Run tests + run: ./gradlew test --no-daemon diff --git a/api-test/order.http b/api-test/order.http index eb8451d..9a467eb 100644 --- a/api-test/order.http +++ b/api-test/order.http @@ -340,7 +340,6 @@ Authorization: Bearer {{ord_userToken}} "reservationId": "{{ord_reservation_cancel}}", "orderName": "미슐랭 코스 취소용 주문", "receivingMethod": "PICKUP", - "expiredAt": "2026-06-01T18:00:00", "items": [ { "optionId": "{{ord_option_id_1_1}}", "quantity": 1 } ] } @@ -412,7 +411,6 @@ Authorization: Bearer {{ord_userToken}} "restaurantId": "{{ord_restaurantId_2}}", "reservationId": "{{ord_reservation_receive}}", "receivingMethod": "PICKUP", - "expiredAt": "2026-06-01T18:00:00", "items": [ { "optionId": "{{ord_option_id_2_1}}", "quantity": 2 }, { "optionId": "{{ord_option_id_2_2}}", "quantity": 1 } @@ -494,7 +492,6 @@ Authorization: Bearer {{dummy_user_token}} "reservationId": "{{dummy_reservation_id}}", "orderName": "아웃박스 보상 로직 테스트", "receivingMethod": "PICKUP", - "expiredAt": "2026-12-31T18:00:00", "items": [ { "optionId": "{{ord_option_id_2_1}}", @@ -521,7 +518,6 @@ Authorization: Bearer {{dummy_user_token}} "reservationId": "{{dummy_reservation_id}}", "orderName": "아웃박스 취소 로직 테스트", "receivingMethod": "PICKUP", - "expiredAt": "2026-12-31T18:00:00", "items": [ { "optionId": "{{ord_option_id_2_1}}", @@ -557,7 +553,6 @@ Authorization: Bearer {{dummy_user_token}} "reservationId": "{{dummy_reservation_id}}", "orderName": "아웃박스 스케줄러 보상 테스트", "receivingMethod": "PICKUP", - "expiredAt": "2026-12-31T18:00:00", "items": [ { "optionId": "{{ord_option_id_2_1}}", @@ -582,7 +577,6 @@ Authorization: Bearer {{dummy_user_token}} "reservationId": "{{dummy_reservation_id}}", "orderName": "아웃박스 스케줄러 취소 테스트", "receivingMethod": "PICKUP", - "expiredAt": "2026-12-31T18:00:00", "items": [ { "optionId": "{{ord_option_id_2_1}}", @@ -670,7 +664,6 @@ Authorization: Bearer {{dummy_user_token}} "reservationId": "{{dummy_reservation_id}}", "orderName": "정상 트랜잭션 분리 테스트", "receivingMethod": "PICKUP", - "expiredAt": "2026-06-01T18:00:00", "items": [ { "optionId": "{{ord_option_id_2_1}}", @@ -708,7 +701,6 @@ Authorization: Bearer {{ord_userToken}} "reservationId": "{{fresh_test_reservation_id}}", "orderName": "실제 데이터 기반 보상 로직 테스트", "receivingMethod": "PICKUP", - "expiredAt": "2026-12-31T18:00:00", "items": [ { "optionId": "{{ord_option_id_2_1}}", @@ -742,7 +734,6 @@ Content-Type: application/json "reservationId": "{{$random.uuid}}", "orderName": "취소할 테스트 주문", "receivingMethod": "PICKUP", - "expiredAt": "2026-06-01T18:00:00", "items": [ { "optionId": "44444444-4444-4444-4444-444444444444", "quantity": 1 } ] @@ -779,7 +770,6 @@ Content-Type: application/json "orderName": "Saga 비동기 E2E 테스트 주문", "receivingMethod": "PICKUP", "reservedDate": "{{ord_targetDate_receive}}", - "expiredAt": "2026-06-01T18:00:00", "items": [ { "optionId": "44444444-4444-4444-4444-444444444444", @@ -850,7 +840,6 @@ Content-Type: application/json "reservationId": "{{$random.uuid}}", "orderName": "Saga 비동기 강제 취소(거절) 테스트", "receivingMethod": "PICKUP", - "expiredAt": "2026-12-31T18:00:00", "items": [ { "optionId": "{{ord_option_id_2_1_kafka}}", @@ -896,7 +885,6 @@ Content-Type: application/json "reservationId": "{{$random.uuid}}", "orderName": "결정적 UUID 멱등성 테스트", "receivingMethod": "PICKUP", - "expiredAt": "2026-12-31T18:00:00", "items": [ { "optionId": "{{ord_option_id_2_1_kafka}}", @@ -948,7 +936,6 @@ Content-Type: application/json "reservationId": "{{$random.uuid}}", "orderName": "단일 토픽 순서 보장 테스트 주문", "receivingMethod": "PICKUP", - "expiredAt": "2026-12-31T18:00:00", "items": [ { "optionId": "{{ord_option_id_2_1_kafka}}", @@ -1001,7 +988,6 @@ Content-Type: application/json "reservationId": "{{$random.uuid}}", "orderName": "단일 토픽 순서 보장 테스트 주문", "receivingMethod": "PICKUP", - "expiredAt": "2026-12-31T18:00:00", "items": [ { "optionId": "{{ord_option_id_2_1_kafka}}", diff --git a/src/main/java/com/michelet/order/application/OrderCommandService.java b/src/main/java/com/michelet/order/application/OrderCommandService.java index c133843..7e58919 100644 --- a/src/main/java/com/michelet/order/application/OrderCommandService.java +++ b/src/main/java/com/michelet/order/application/OrderCommandService.java @@ -103,7 +103,6 @@ public OrderResult createOrder(CreateOrderCommand command) { finalOrderName, verifiedDate, // 포트를 통해 받아온 날짜 method, - command.expiredAt(), orderItems ); diff --git a/src/main/java/com/michelet/order/application/dto/CreateOrderCommand.java b/src/main/java/com/michelet/order/application/dto/CreateOrderCommand.java index 4e4e122..67d1d0c 100644 --- a/src/main/java/com/michelet/order/application/dto/CreateOrderCommand.java +++ b/src/main/java/com/michelet/order/application/dto/CreateOrderCommand.java @@ -1,6 +1,5 @@ package com.michelet.order.application.dto; -import java.time.LocalDateTime; import java.util.List; import java.util.Objects; import java.util.UUID; @@ -11,14 +10,12 @@ public record CreateOrderCommand( UUID restaurantId, String orderName, String receivingMethod, - LocalDateTime expiredAt, List items ) { public CreateOrderCommand { Objects.requireNonNull(userId, "userId는 필수입니다."); Objects.requireNonNull(reservationId, "reservationId는 필수입니다."); Objects.requireNonNull(restaurantId, "restaurantId는 필수입니다."); - Objects.requireNonNull(expiredAt, "expiredAt은 필수입니다."); if (items == null || items.isEmpty()) { throw new IllegalArgumentException("주문 항목은 최소 1개 이상이어야 합니다."); } diff --git a/src/main/java/com/michelet/order/domain/model/Order.java b/src/main/java/com/michelet/order/domain/model/Order.java index 9defca3..cce87a3 100644 --- a/src/main/java/com/michelet/order/domain/model/Order.java +++ b/src/main/java/com/michelet/order/domain/model/Order.java @@ -99,7 +99,7 @@ private Order(UUID userId, UUID reservationId, UUID restaurantId, String orderNa } public static Order create(UUID userId, UUID reservationId, UUID restaurantId, String orderName, - LocalDate reservedDate, ReceivingMethod receivingMethod, LocalDateTime expiredAt, + LocalDate reservedDate, ReceivingMethod receivingMethod, List items) { // 필수 값에 대한 Fail-fast 검증 Objects.requireNonNull(userId, "userId는 필수입니다."); @@ -109,19 +109,24 @@ public static Order create(UUID userId, UUID reservationId, UUID restaurantId, S throw new IllegalArgumentException("orderName은 필수이며 비어있을 수 없습니다."); } Objects.requireNonNull(reservedDate, "reservedDate는 필수입니다."); - Objects.requireNonNull(expiredAt, "expiredAt은 필수입니다."); if (items == null || items.isEmpty()) { throw new IllegalArgumentException("주문 항목은 최소 1개 이상이어야 합니다."); } + + ReceivingMethod normalizedReceivingMethod = + receivingMethod != null ? receivingMethod : ReceivingMethod.PICKUP; + + LocalDateTime calculatedExpiredAt = calculateExpiredAt(normalizedReceivingMethod); + Order order = Order.builder() .userId(userId) .reservationId(reservationId) .restaurantId(restaurantId) .orderName(orderName) .reservedDate(reservedDate) - .receivingMethod(receivingMethod) - .expiredAt(expiredAt) + .receivingMethod(normalizedReceivingMethod) // 정규화된 값 주입 + .expiredAt(calculatedExpiredAt) // 정확히 계산된 시간 주입 .build(); // addOrderItem 내부에서 점진적 덧셈을 하므로 N^2 문제 해결 및 별도 calculateTotalAmount 호출 불필요해짐! @@ -233,4 +238,12 @@ public void receive(LocalDate currentDate) { } this.status = OrderStatus.RECEIVED; } + + private static LocalDateTime calculateExpiredAt(ReceivingMethod receivingMethod) { + LocalDateTime now = LocalDateTime.now(); + if (receivingMethod == ReceivingMethod.PICKUP) { + return now.toLocalDate().atTime(23, 0); // 당일 23시 00분 + } + return now.plusMinutes(15); // 그 외(SHIPPING 등)는 현재 시간 + 15분 + } } diff --git a/src/main/java/com/michelet/order/infrastructure/config/FeignConfig.java b/src/main/java/com/michelet/order/infrastructure/config/FeignConfig.java index 339145c..cbcd29d 100644 --- a/src/main/java/com/michelet/order/infrastructure/config/FeignConfig.java +++ b/src/main/java/com/michelet/order/infrastructure/config/FeignConfig.java @@ -15,7 +15,6 @@ public class FeignConfig { private final InternalTokenIssuer internalTokenIssuer; - //FIXME 아직 수정 안한 서비스들 호환을 위해 일단 넣음 - 나중엔 이 부분 삭제 @Bean public RequestInterceptor internalAuthRequestInterceptor() { return template -> { @@ -54,37 +53,3 @@ public ErrorDecoder errorDecoder() { }; } } - -//TODO 다른 서비스들 다 feign 연결 끝나면 아래 활성화 -//package com.michelet.order.infrastructure.config; -// -//import com.michelet.common.auth.feign.interceptor.InternalFeignInterceptor; -//import com.michelet.common.auth.feign.internal.InternalTokenIssuer; -//import com.michelet.common.auth.feign.config.InternalFeignProperties; -//import feign.RequestInterceptor; -//import feign.codec.ErrorDecoder; -//import org.springframework.context.annotation.Bean; -//import org.springframework.context.annotation.Configuration; -// -//@Configuration -//public class FeignConfig { -// -// @Bean -// public RequestInterceptor internalFeignInterceptor( -// InternalTokenIssuer internalTokenIssuer, -// InternalFeignProperties properties -// ) { -// return new InternalFeignInterceptor(internalTokenIssuer, properties); -// } -// -// @Bean -// public ErrorDecoder errorDecoder() { -// // 에러 로깅 및 예외 변환 로직만 남기기 -// return (methodKey, response) -> { -// if (response.status() >= 400 && response.status() < 500) { -// return new IllegalArgumentException("내부 통신 인증 실패"); -// } -// return new RuntimeException("외부 서비스 서버 오류"); -// }; -// } -//} diff --git a/src/main/java/com/michelet/order/presentation/OrderController.java b/src/main/java/com/michelet/order/presentation/OrderController.java index f1ff013..ce02b0a 100644 --- a/src/main/java/com/michelet/order/presentation/OrderController.java +++ b/src/main/java/com/michelet/order/presentation/OrderController.java @@ -52,7 +52,7 @@ public ResponseEntity> cancelOrder(@PathVariable UUID orderId) return ResponseEntity.ok(ApiResponse.ok(null)); } - // TODO: 나중에 실제 해당 레스토랑의 오너인지 검증하는 로직 추가 필요 (@CheckOwner 등 AOP 적용 예정) + // NOTE: 나중에 실제 해당 레스토랑의 오너인지 검증하는 로직 추가 필요 (@CheckOwner 등 AOP 적용 예정) @RequireRole(UserRole.OWNER) @PatchMapping("/{orderId}/receive") public ResponseEntity> receiveOrder(@PathVariable UUID orderId) { @@ -63,7 +63,7 @@ public ResponseEntity> receiveOrder(@PathVariable UUID orderId return ResponseEntity.ok(ApiResponse.ok(null)); } - // TODO: 나중에 테스트 완료 후 `@CheckOwner` 또는 소유자 검증 AOP 적용 필요 - 현재 인가 검증 미적용 + // NOTE: 나중에 테스트 완료 후 `@CheckOwner` 또는 소유자 검증 AOP 적용 필요 - 현재 인가 검증 미적용 @RequireRole({UserRole.USER, UserRole.OWNER, UserRole.MASTER}) // 최소한의 인증(로그인 여부)만 요구하도록 추가 @GetMapping("/{orderId}") public ResponseEntity> getOrder(@PathVariable UUID orderId) { @@ -71,7 +71,7 @@ public ResponseEntity> getOrder(@PathVariable UUID orde return ResponseEntity.ok(ApiResponse.ok(result)); } - // TODO: 나중에 결제 시스템 연동 완료 시 웹훅 등으로 변경 예정 + 해당 레스토랑 오너 검증 로직 추가 필요 (@CheckOwner AOP 도입) + // NOTE: 나중에 결제 시스템 연동 완료 시 웹훅 등으로 변경 예정 + 해당 레스토랑 오너 검증 로직 추가 필요 (@CheckOwner AOP 도입) @RequireRole(UserRole.OWNER) @PatchMapping("/{orderId}/complete") public ResponseEntity> completeOrder(@PathVariable UUID orderId) { diff --git a/src/main/java/com/michelet/order/presentation/dto/CreateOrderRequest.java b/src/main/java/com/michelet/order/presentation/dto/CreateOrderRequest.java index e7a4819..c3f8ef4 100644 --- a/src/main/java/com/michelet/order/presentation/dto/CreateOrderRequest.java +++ b/src/main/java/com/michelet/order/presentation/dto/CreateOrderRequest.java @@ -6,7 +6,6 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; -import java.time.LocalDateTime; import java.util.List; import java.util.UUID; @@ -15,7 +14,6 @@ public record CreateOrderRequest( @NotNull UUID restaurantId, String orderName, @NotBlank String receivingMethod, - @NotNull LocalDateTime expiredAt, @NotEmpty List<@Valid OrderItemRequest> items ) { public record OrderItemRequest( @@ -31,7 +29,6 @@ public CreateOrderCommand toCommand(UUID userId) { restaurantId, orderName, receivingMethod, - expiredAt, items.stream().map(it -> new CreateOrderCommand.OrderItemCommand( it.optionId(), it.quantity() )).toList() diff --git a/src/test/java/com/michelet/order/application/OrderCommandServiceTest.java b/src/test/java/com/michelet/order/application/OrderCommandServiceTest.java index c0565c6..7f82ca1 100644 --- a/src/test/java/com/michelet/order/application/OrderCommandServiceTest.java +++ b/src/test/java/com/michelet/order/application/OrderCommandServiceTest.java @@ -23,7 +23,6 @@ import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -81,7 +80,6 @@ void createOrder_Success_Calculation() { UUID.randomUUID(), null, // 자동 생성을 위해 orderName은 null로 설정 "PICKUP", - LocalDateTime.now().plusHours(2), List.of( new CreateOrderCommand.OrderItemCommand(optionId1, 2), new CreateOrderCommand.OrderItemCommand(optionId2, 3) @@ -197,7 +195,6 @@ void cancelOrder_Success_ShouldSaveOutbox() { "테스트 주문", LocalDate.now().plusDays(1), ReceivingMethod.PICKUP, - LocalDateTime.now().plusHours(2), List.of(item) ); @@ -240,7 +237,6 @@ void createOrder_Fail_EmptyItems() { UUID.randomUUID(), "빈 주문", "PICKUP", - LocalDateTime.now().plusHours(2), List.of() // 빈 리스트 전달 )) .isInstanceOf(IllegalArgumentException.class) @@ -268,7 +264,6 @@ private Order createMockOrder(OrderStatus status) { "테스트", LocalDate.now().plusDays(1), ReceivingMethod.PICKUP, - LocalDateTime.now().plusHours(2), List.of( OrderItem.create( UUID.randomUUID(), diff --git a/src/test/java/com/michelet/order/domain/model/OrderTest.java b/src/test/java/com/michelet/order/domain/model/OrderTest.java index 1b6707b..8c3152f 100644 --- a/src/test/java/com/michelet/order/domain/model/OrderTest.java +++ b/src/test/java/com/michelet/order/domain/model/OrderTest.java @@ -6,6 +6,7 @@ import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.List; import java.util.UUID; import org.junit.jupiter.api.DisplayName; @@ -28,7 +29,6 @@ void createOrder_TotalAmountCalculation() { "테스트 주문", LocalDate.now(), ReceivingMethod.PICKUP, - LocalDateTime.now().plusHours(2), List.of(item1, item2) ); @@ -90,7 +90,6 @@ private Order createDefaultOrder() { "테스트 주문", LocalDate.now().plusDays(1), // 방문 예정일을 '내일'로 설정하여 오늘 취소 가능하도록 보장 ReceivingMethod.PICKUP, - LocalDateTime.now().plusHours(2), List.of(item)); } @@ -104,7 +103,6 @@ private Order createDefaultOrderForToday() { "오늘 주문", LocalDate.now(), // 오늘 날짜 ReceivingMethod.PICKUP, - LocalDateTime.now().plusHours(2), List.of(item)); } @@ -121,4 +119,52 @@ void statusTransition_Fail_CanceledToCompleted() { .isInstanceOf(IllegalStateException.class) .hasMessageContaining("주문 완료가 불가능한 상태입니다."); } + + @Test + @DisplayName("성공: PICKUP 수령 시 만료 시간은 당일 23시로 자동 계산된다") + void createOrder_ExpiredAt_Pickup() { + // given + OrderItem item = OrderItem.create(UUID.randomUUID(), "상품A", new BigDecimal("10000"), 1); + + // 생성 직전의 시점 캡처 + LocalDateTime beforeCreate = LocalDateTime.now(); + + // when + Order order = Order.create( + UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), + "테스트 주문", LocalDate.now(), ReceivingMethod.PICKUP, List.of(item) + ); + + // 생성 직후의 시점 캡처 + LocalDateTime afterCreate = LocalDateTime.now(); + + // then + // 날짜가 자정 경계선에서 바뀌었더라도 before와 after 사이에 있는지 검증 + assertThat(order.getExpiredAt().toLocalDate()) + .isIn(beforeCreate.toLocalDate(), afterCreate.toLocalDate()); + + assertThat(order.getExpiredAt().toLocalTime()).isEqualTo(LocalTime.of(23, 0)); + } + + @Test + @DisplayName("성공: SHIPPING (그 외) 수령 시 만료 시간은 현재 시간 + 15분으로 자동 계산된다") + void createOrder_ExpiredAt_Shipping() { + // given + OrderItem item = OrderItem.create(UUID.randomUUID(), "상품B", new BigDecimal("10000"), 1); + LocalDateTime beforeCreate = LocalDateTime.now(); + + // when + Order order = Order.create( + UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), + "테스트 주문", LocalDate.now(), ReceivingMethod.SHIPPING, List.of(item) + ); + LocalDateTime afterCreate = LocalDateTime.now(); + + // then + // 실행 시간에 따른 미세한 오차를 허용하기 위해 isBetween 사용 + assertThat(order.getExpiredAt()).isBetween( + beforeCreate.plusMinutes(15), + afterCreate.plusMinutes(15) + ); + } } diff --git a/src/test/java/com/michelet/order/infrastructure/repository/OrderAuditingTest.java b/src/test/java/com/michelet/order/infrastructure/repository/OrderAuditingTest.java index 456ffa3..180a290 100644 --- a/src/test/java/com/michelet/order/infrastructure/repository/OrderAuditingTest.java +++ b/src/test/java/com/michelet/order/infrastructure/repository/OrderAuditingTest.java @@ -9,7 +9,6 @@ import com.michelet.order.infrastructure.config.AuditorConfig; import java.math.BigDecimal; import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.List; import java.util.UUID; import org.junit.jupiter.api.DisplayName; @@ -38,7 +37,6 @@ void auditing_CreatedBy_ShouldMatchTestAuditor() { "Auditing 테스트", LocalDate.now(), ReceivingMethod.PICKUP, - LocalDateTime.now().plusHours(2), List.of(item)); // when diff --git a/src/test/java/com/michelet/order/infrastructure/repository/OrderPersistenceTest.java b/src/test/java/com/michelet/order/infrastructure/repository/OrderPersistenceTest.java index b28daf7..c0e7af9 100644 --- a/src/test/java/com/michelet/order/infrastructure/repository/OrderPersistenceTest.java +++ b/src/test/java/com/michelet/order/infrastructure/repository/OrderPersistenceTest.java @@ -1,11 +1,17 @@ package com.michelet.order.infrastructure.repository; +import static org.assertj.core.api.Assertions.assertThat; + import com.michelet.common.config.JpaAuditingConfig; import com.michelet.order.domain.model.Order; import com.michelet.order.domain.model.OrderItem; import com.michelet.order.domain.model.ReceivingMethod; import com.michelet.order.infrastructure.config.AuditorConfig; import jakarta.persistence.EntityManager; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; +import java.util.UUID; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -13,14 +19,6 @@ import org.springframework.context.annotation.Import; import org.springframework.test.context.ActiveProfiles; -import java.math.BigDecimal; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.List; -import java.util.UUID; - -import static org.assertj.core.api.Assertions.assertThat; - @DataJpaTest @Import({AuditorConfig.class, JpaAuditingConfig.class}) @ActiveProfiles("test") @@ -42,7 +40,7 @@ void removeOrderItem_ShouldDeleteOrphan() { Order order = Order.create( UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), " 공백 포함 주문명 ", // 테스트용 공백 - LocalDate.now(), ReceivingMethod.PICKUP, LocalDateTime.now().plusHours(2), + LocalDate.now(), ReceivingMethod.PICKUP, List.of(item1, item2) );