diff --git a/src/main/java/org/store/clothstar/productLine/controller/ProductLineController.java b/src/main/java/org/store/clothstar/productLine/controller/ProductLineController.java index ddf1e0ae..8fc443f5 100644 --- a/src/main/java/org/store/clothstar/productLine/controller/ProductLineController.java +++ b/src/main/java/org/store/clothstar/productLine/controller/ProductLineController.java @@ -3,6 +3,8 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.hibernate.query.Page; +import org.springframework.data.web.PageableDefault; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; @@ -15,33 +17,41 @@ import org.store.clothstar.productLine.dto.response.ProductLineWithProductsJPAResponse; import org.store.clothstar.productLine.service.ProductLineService; +import java.awt.print.Pageable; import java.net.URI; import java.util.List; @Tag(name = "ProductLines", description = "ProductLine 관련 API 입니다.") @RestController @RequiredArgsConstructor -@RequestMapping("/v1/productLines") +//@RequestMapping("/v1/productLines") public class ProductLineController { private final ProductLineService productLineService; @Operation(summary = "전체 상품 조회", description = "삭제되지 않은 모든 상품을 조회한다.") - @GetMapping + @GetMapping("/v1/productLines") public ResponseEntity> getAllProductLines() { List productLineResponses = productLineService.getAllProductLines(); return ResponseEntity.ok().body(productLineResponses); } + @Operation(summary = "전체 상품 조회", description = "삭제되지 않은 모든 상품을 조회한다.") + @GetMapping("/v1/productLines") + public ResponseEntity> getAllProductLines(@PageableDefault(size = 18) Pageable pageable) { + List productLineResponses = productLineService.getAllProductLines(); + return ResponseEntity.ok().body(productLineResponses); + } + @Operation(summary = "상품 상세 조회", description = "productLineId로 상품과 하위 옵션들을 상세 조회한다.") - @GetMapping("/{productLineId}") + @GetMapping("/v1/productLines/{productLineId}") public ResponseEntity getProductLine(@PathVariable("productLineId") Long productLineId) { ProductLineWithProductsJPAResponse productLineWithProducts = productLineService.getProductLineWithProducts(productLineId); return ResponseEntity.ok().body(productLineWithProducts); } @Operation(summary = "상품 등록", description = "카테고리 아이디, 상품 이름, 내용, 가격, 상태를 입력하여 상품을 신규 등록한다.") - @PostMapping + @PostMapping("/v1/productLines") public ResponseEntity createProductLine(@Validated @RequestBody CreateProductLineRequest createProductLineRequest) { Long productLineId = productLineService.createProductLine(createProductLineRequest); URI location = URIBuilder.buildURI(productLineId); @@ -50,7 +60,7 @@ public ResponseEntity createProductLine(@Validated @RequestBody CreateProdu } @Operation(summary = "상품 수정", description = "상품 이름, 가격, 재고, 상태를 입력하여 상품 정보를 수정한다.") - @PutMapping("/{productLineId}") + @PutMapping("/v1/productLines/{productLineId}") public ResponseEntity updateProductLine( @PathVariable Long productLineId, @Validated @RequestBody UpdateProductLineRequest updateProductLineRequest) { @@ -60,7 +70,7 @@ public ResponseEntity updateProductLine( return ResponseEntity.ok().body(new MessageDTO(HttpStatus.OK.value(), "ProductLine updated successfully")); } - @DeleteMapping("/{productLineId}") + @DeleteMapping("/v1/productLines/{productLineId}") public ResponseEntity deleteProductLine(@PathVariable("productLineId") Long productLineId) { productLineService.setDeletedAt(productLineId); return ResponseEntity.noContent().build(); diff --git a/src/main/java/org/store/clothstar/productLine/dto/response/ProductLineWithProductsJPAResponse.java b/src/main/java/org/store/clothstar/productLine/dto/response/ProductLineWithProductsJPAResponse.java index 6bb4897a..e7808ffb 100644 --- a/src/main/java/org/store/clothstar/productLine/dto/response/ProductLineWithProductsJPAResponse.java +++ b/src/main/java/org/store/clothstar/productLine/dto/response/ProductLineWithProductsJPAResponse.java @@ -26,24 +26,20 @@ public class ProductLineWithProductsJPAResponse { private Long productLineId; - private CategoryResponse category; private String name; private String content; private int price; private Long totalStock; private ProductLineStatus status; - // private List productList; private List productList; private Long saleCount; // ~개 판매중 - private MemberSimpleResponse member; private SellerSimpleResponse seller; @JsonSerialize(using = LocalDateTimeSerializer.class) private LocalDateTime createdAt; private LocalDateTime modifiedAt; -// private LocalDateTime deletedAt; // @QueryProjection -// public ProductLineWithProductsJPAResponse(ProductLineEntity productLine, Category category, SellerEntity seller, Member member, Long totalStock) { +// public ProductLineWithProductsJPAResponse(ProductLineEntity productLine, Category category, SellerEntity seller, MemberEntity member, Long totalStock) { // this.productLineId = productLine.getProductLineId(); // this.category = CategoryResponse.from(category); // this.name = productLine.getName(); @@ -64,21 +60,19 @@ public class ProductLineWithProductsJPAResponse { // } // 추가된 생성자 - public ProductLineWithProductsJPAResponse(ProductLineEntity productLine, CategoryEntity category, Seller seller, Member member, Long totalStock, List productList) { + public ProductLineWithProductsJPAResponse(ProductLineEntity productLine, CategoryEntity category, SellerEntity seller, MemberEntity member, Long totalStock, List productList) { this(productLine, category, seller, member, totalStock); this.productList = productList != null ? productList : new ArrayList<>(); } @QueryProjection - public ProductLineWithProductsJPAResponse(ProductLineEntity productLine, CategoryEntity category, Seller seller, Member member, Long totalStock) { + public ProductLineWithProductsJPAResponse(ProductLineEntity productLine, SellerEntity seller, Long totalStock) { this.productLineId = productLine.getProductLineId(); - this.category = CategoryResponse.from(category); this.name = productLine.getName(); this.price = productLine.getPrice(); this.totalStock = totalStock; this.status = productLine.getStatus(); this.saleCount = productLine.getSaleCount(); - this.member = MemberSimpleResponse.from(member); this.seller = SellerSimpleResponse.from(seller); this.createdAt = productLine.getCreatedAt(); this.modifiedAt = productLine.getModifiedAt(); diff --git a/src/main/java/org/store/clothstar/productLine/repository/ProductLineRepository.java b/src/main/java/org/store/clothstar/productLine/repository/ProductLineRepository.java deleted file mode 100644 index 38429a7d..00000000 --- a/src/main/java/org/store/clothstar/productLine/repository/ProductLineRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.store.clothstar.productLine.repository; - -import org.store.clothstar.productLine.domain.ProductLine; -import org.store.clothstar.productLine.dto.response.ProductLineWithProductsResponse; - -import java.util.List; -import java.util.Optional; - -public interface ProductLineRepository { - - List selectAllProductLinesNotDeleted(); - - Optional selectByProductLineId(Long productId); - - Optional selectProductLineWithOptions(Long productId); - - int save(ProductLine productLine); - - int updateProductLine(ProductLine productLine); - - int setDeletedAt(ProductLine productLine); -} diff --git a/src/main/java/org/store/clothstar/productLine/repository/ProductLineRepositoryCustomImpl.java b/src/main/java/org/store/clothstar/productLine/repository/ProductLineRepositoryCustomImpl.java index 41da1251..4fa33b29 100644 --- a/src/main/java/org/store/clothstar/productLine/repository/ProductLineRepositoryCustomImpl.java +++ b/src/main/java/org/store/clothstar/productLine/repository/ProductLineRepositoryCustomImpl.java @@ -66,7 +66,7 @@ public Page getProductLinesWithOptions(Pagea ProductEntity product = tuple.get(qProduct); ProductLineWithProductsJPAResponse response = productLineMap.computeIfAbsent(productLine.getProductLineId(), - id -> new ProductLineWithProductsJPAResponse(productLine, category, seller, member, productLine.getProducts().stream().mapToLong(ProductEntity::getStock).sum())); + id -> new ProductLineWithProductsJPAResponse(productLine, seller, productLine.getProducts().stream().mapToLong(ProductEntity::getStock).sum())); if (product != null) { response.getProductList().add(ProductResponse.from(product)); @@ -91,15 +91,11 @@ public Optional findProductLineWithOptionsBy ProductLineWithProductsJPAResponse result = jpaQueryFactory .select(new QProductLineWithProductsJPAResponse( qProductLine, - qCategory, qSeller, - qMember, totalStockExpression )) .from(qProductLine) .innerJoin(qProductLine.seller, qSeller) - .innerJoin(qSeller.member, qMember) - .innerJoin(qProductLine.category, qCategory) .leftJoin(qProductLine.products, qProduct) .where(qProductLine.productLineId.eq(productLineId) .and(qProductLine.deletedAt.isNull())) diff --git a/src/test/java/org/store/clothstar/productLine/controller/ProductLineControllerIntegrationTest.java b/src/test/java/org/store/clothstar/productLine/controller/ProductLineControllerIntegrationTest.java index 1a36aa35..072bd360 100644 --- a/src/test/java/org/store/clothstar/productLine/controller/ProductLineControllerIntegrationTest.java +++ b/src/test/java/org/store/clothstar/productLine/controller/ProductLineControllerIntegrationTest.java @@ -1,229 +1,230 @@ -package org.store.clothstar.productLine.controller; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.Disabled; -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.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.ResultActions; -import org.springframework.transaction.annotation.Transactional; -import org.store.clothstar.productLine.domain.ProductLine; -import org.store.clothstar.productLine.domain.type.ProductLineStatus; -import org.store.clothstar.productLine.dto.request.CreateProductLineRequest; -import org.store.clothstar.productLine.dto.request.UpdateProductLineRequest; -import org.store.clothstar.productLine.dto.response.ProductLineResponse; -import org.store.clothstar.productLine.dto.response.ProductLineWithProductsResponse; -import org.store.clothstar.productLine.repository.ProductLineRepository; -import org.store.clothstar.productLine.service.ProductLineService; - -import java.util.ArrayList; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -@SpringBootTest -@AutoConfigureMockMvc -@Transactional -@Disabled -public class ProductLineControllerIntegrationTest { - - @Autowired - private MockMvc mockMvc; - - @Autowired - private ObjectMapper objectMapper; - - @Autowired - private ProductLineService productLineService; - - @Autowired - private ProductLineRepository productLineRepository; - - private static final String PRODUCT_LINE_URL = "/v1/productLines"; - - - @Test - @DisplayName("전체 상품 조회 시 모든 ProductLine이 반환된다.") - void whenGetAllProductLines_thenAllExistingAndNewProductLinesAreReturned() throws Exception { - // given - // 기존 데이터 개수 확인 - int initialCount = productLineRepository.selectAllProductLinesNotDeleted().size(); - - // 새로운 ProductLine 추가 - List newProductLineIds = createSampleProductLines(3); - int expectedTotalCount = initialCount + 3; - - // when - ResultActions actions = mockMvc.perform(get(PRODUCT_LINE_URL) - .contentType(MediaType.APPLICATION_JSON)); - - // then - actions.andExpect(status().isOk()) - .andExpect(jsonPath("$.length()").value(expectedTotalCount)) - .andDo(print()); - - String responseBody = actions.andReturn().getResponse().getContentAsString(); - List responses = objectMapper.readValue(responseBody, new TypeReference>() { - }); - - assertThat(responses).hasSize(expectedTotalCount); - - // 새로 추가한 ProductLine 확인 - for (Long id : newProductLineIds) { - ProductLine productLine = productLineRepository.selectByProductLineId(id).orElseThrow(); - ProductLineResponse response = responses.stream() - .filter(r -> r.getProductLineStatus().equals(id)) - .findFirst() - .orElseThrow(); - - assertThat(response.getProductLineId()).isEqualTo(productLine.getProductLineId()); - assertThat(response.getName()).isEqualTo(productLine.getName()); - assertThat(response.getPrice()).isEqualTo(productLine.getPrice()); - assertThat(response.getContent()).isEqualTo(productLine.getContent()); - assertThat(response.getBrandName()).isEqualTo(productLine.getBrandName()); - assertThat(response.getProductLineStatus()).isEqualTo(productLine.getStatus()); - } - - // 기존 데이터도 포함되어 있는지 확인 (샘플로 첫 번째 항목 확인) - if (initialCount > 0) { - ProductLine firstExistingProductLine = productLineRepository.selectAllProductLinesNotDeleted().get(0); - ProductLineResponse firstResponse = responses.stream() - .filter(r -> r.getProductLineStatus().equals(firstExistingProductLine.getProductLineId())) - .findFirst() - .orElseThrow(); - - assertThat(firstResponse.getProductLineStatus()).isEqualTo(firstExistingProductLine.getProductLineId()); - assertThat(firstResponse.getName()).isEqualTo(firstExistingProductLine.getName()); - assertThat(firstResponse.getPrice()).isEqualTo(firstExistingProductLine.getPrice()); - assertThat(firstResponse.getProductLineStatus()).isEqualTo(firstExistingProductLine.getStatus()); - } - } - - @Test - @DisplayName("특정 ProductLine ID로 조회 시 해당 ProductLine과 관련 Products가 반환된다.") - void givenProductLineId_whenGetProductLineWithProducts_thenProductLineWithProductsIsReturned() throws Exception { - // given - ProductLine productLine = createSampleProductLine(); - String url = PRODUCT_LINE_URL + "/" + productLine.getProductLineId(); - - // when - ResultActions actions = mockMvc.perform(get(url) - .contentType(MediaType.APPLICATION_JSON)); - - // then - actions.andExpect(status().isOk()) - .andExpect(jsonPath("$.id").value(productLine.getProductLineId())) - .andDo(print()); - - String responseBody = actions.andReturn().getResponse().getContentAsString(); - ProductLineWithProductsResponse response = objectMapper.readValue(responseBody, ProductLineWithProductsResponse.class); - - assertThat(response.getProductLineId()).isEqualTo(productLine.getProductLineId()); - assertThat(response.getName()).isEqualTo(productLine.getName()); - assertThat(response.getContent()).isEqualTo(productLine.getContent()); - assertThat(response.getPrice()).isEqualTo(productLine.getPrice()); - assertThat(response.getStatus()).isEqualTo(productLine.getStatus()); - // 여기에 하위 제품(Products) 검증 로직 추가 - } - - @Test - @DisplayName("새로운 ProductLine 생성 요청 시 정상적으로 생성되고 반환된다.") - void givenValidProductLineRequest_whenCreateProductLine_thenProductLineIsCreatedAndReturned() throws Exception { - // given - CreateProductLineRequest request = new CreateProductLineRequest( - 1L, "New Product", "Description", 10000, ProductLineStatus.FOR_SALE); - String content = objectMapper.writeValueAsString(request); - - // when - ResultActions actions = mockMvc.perform(post(PRODUCT_LINE_URL) - .contentType(MediaType.APPLICATION_JSON) - .content(content)); - - // then - actions.andExpect(status().isCreated()) - .andExpect(header().exists("Location")) - .andDo(print()); - - String locationHeader = actions.andReturn().getResponse().getHeader("Location"); - Long productLineId = Long.parseLong(locationHeader.substring(locationHeader.lastIndexOf("/") + 1)); - - ProductLine createdProductLine = productLineRepository.selectByProductLineId(productLineId).orElseThrow(); - - assertThat(createdProductLine.getProductLineId()).isEqualTo(productLineId); - assertThat(createdProductLine.getCategoryId()).isEqualTo(request.getCategoryId()); - assertThat(createdProductLine.getName()).isEqualTo(request.getName()); - assertThat(createdProductLine.getContent()).isEqualTo(request.getContent()); - assertThat(createdProductLine.getPrice()).isEqualTo(request.getPrice()); - assertThat(createdProductLine.getStatus()).isEqualTo(request.getStatus()); - } - - @Test - @DisplayName("기존 ProductLine 수정 요청 시 정상적으로 수정되는지 확인") - void givenProductLineIdAndUpdateRequest_whenUpdateProductLine_thenProductLineIsUpdated() throws Exception { - // given - ProductLine originalProductLine = createSampleProductLine(); - UpdateProductLineRequest request = new UpdateProductLineRequest( - "Updated Product", "Updated Content", 100, ProductLineStatus.FOR_SALE); - String content = objectMapper.writeValueAsString(request); - String url = PRODUCT_LINE_URL + "/" + originalProductLine.getProductLineId(); - - // when - ResultActions actions = mockMvc.perform(put(url) - .contentType(MediaType.APPLICATION_JSON) - .content(content)); - - // then - actions.andExpect(status().isOk()) - .andExpect(jsonPath("$.message").value("ProductLine updated successfully")) - .andDo(print()); - - ProductLine updatedProductLine = productLineRepository.selectByProductLineId(originalProductLine.getProductLineId()).orElseThrow(); - - assertThat(updatedProductLine.getProductLineId()).isEqualTo(originalProductLine.getProductLineId()); - assertThat(updatedProductLine.getName()).isEqualTo(request.getName()); - assertThat(updatedProductLine.getContent()).isEqualTo(request.getContent()); - assertThat(updatedProductLine.getPrice()).isEqualTo(request.getPrice()); - assertThat(updatedProductLine.getStatus()).isEqualTo(request.getStatus()); - } - - @Test - @DisplayName("ProductLine 삭제 요청 시 정상적으로 삭제(soft delete)되는지 확인") - void givenProductLineId_whenDeleteProductLine_thenProductLineIsSoftDeleted() throws Exception { - // given - ProductLine productLine = createSampleProductLine(); - String url = PRODUCT_LINE_URL + "/" + productLine.getProductLineId(); - - // when - ResultActions actions = mockMvc.perform(delete(url) - .contentType(MediaType.APPLICATION_JSON)); - - // then - actions.andExpect(status().isNoContent()); - - ProductLine deletedProductLine = productLineRepository.selectByProductLineId(productLine.getProductLineId()).orElseThrow(); - assertThat(deletedProductLine.getDeletedAt()).isNotNull(); - } - - private ProductLine createSampleProductLine() { - CreateProductLineRequest request = new CreateProductLineRequest( - 1L, "Sample Product", "Description", 10000, ProductLineStatus.FOR_SALE); - Long productLineId = productLineService.createProductLine(request); - return productLineRepository.selectByProductLineId(productLineId).orElseThrow(); - } - - private List createSampleProductLines(int count) { - List ids = new ArrayList<>(); - for (int i = 0; i < count; i++) { - ids.add(createSampleProductLine().getProductLineId()); - } - return ids; - } -} +//package org.store.clothstar.productLine.controller; +// +//import com.fasterxml.jackson.core.type.TypeReference; +//import com.fasterxml.jackson.databind.ObjectMapper; +//import org.junit.jupiter.api.Disabled; +//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.web.servlet.AutoConfigureMockMvc; +//import org.springframework.boot.test.context.SpringBootTest; +//import org.springframework.http.MediaType; +//import org.springframework.test.web.servlet.MockMvc; +//import org.springframework.test.web.servlet.ResultActions; +//import org.springframework.transaction.annotation.Transactional; +//import org.store.clothstar.productLine.domain.ProductLine; +//import org.store.clothstar.productLine.domain.type.ProductLineStatus; +//import org.store.clothstar.productLine.dto.request.CreateProductLineRequest; +//import org.store.clothstar.productLine.dto.request.UpdateProductLineRequest; +//import org.store.clothstar.productLine.dto.response.ProductLineResponse; +//import org.store.clothstar.productLine.dto.response.ProductLineWithProductsResponse; +//import org.store.clothstar.productLine.repository.ProductLineJPARepository; +//import org.store.clothstar.productLine.repository.ProductLineRepository; +//import org.store.clothstar.productLine.service.ProductLineService; +// +//import java.util.ArrayList; +//import java.util.List; +// +//import static org.assertj.core.api.Assertions.assertThat; +//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +//import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +// +//@SpringBootTest +//@AutoConfigureMockMvc +//@Transactional +//@Disabled +//public class ProductLineControllerIntegrationTest { +// +// @Autowired +// private MockMvc mockMvc; +// +// @Autowired +// private ObjectMapper objectMapper; +// +// @Autowired +// private ProductLineService productLineService; +// +// @Autowired +// private ProductLineJPARepository productLineRepository; +// +// private static final String PRODUCT_LINE_URL = "/v1/productLines"; +// +// +// @Test +// @DisplayName("전체 상품 조회 시 모든 ProductLine이 반환된다.") +// void whenGetAllProductLines_thenAllExistingAndNewProductLinesAreReturned() throws Exception { +// // given +// // 기존 데이터 개수 확인 +// int initialCount = productLineRepository.findByDeletedAtIsNullAndStatusNotIn().size(); +// +// // 새로운 ProductLine 추가 +// List newProductLineIds = createSampleProductLines(3); +// int expectedTotalCount = initialCount + 3; +// +// // when +// ResultActions actions = mockMvc.perform(get(PRODUCT_LINE_URL) +// .contentType(MediaType.APPLICATION_JSON)); +// +// // then +// actions.andExpect(status().isOk()) +// .andExpect(jsonPath("$.length()").value(expectedTotalCount)) +// .andDo(print()); +// +// String responseBody = actions.andReturn().getResponse().getContentAsString(); +// List responses = objectMapper.readValue(responseBody, new TypeReference>() { +// }); +// +// assertThat(responses).hasSize(expectedTotalCount); +// +// // 새로 추가한 ProductLine 확인 +// for (Long id : newProductLineIds) { +// ProductLine productLine = productLineRepository.findById(id).orElseThrow(); +// ProductLineResponse response = responses.stream() +// .filter(r -> r.getProductLineStatus().equals(id)) +// .findFirst() +// .orElseThrow(); +// +// assertThat(response.getProductLineId()).isEqualTo(productLine.getProductLineId()); +// assertThat(response.getName()).isEqualTo(productLine.getName()); +// assertThat(response.getPrice()).isEqualTo(productLine.getPrice()); +// assertThat(response.getContent()).isEqualTo(productLine.getContent()); +// assertThat(response.getBrandName()).isEqualTo(productLine.getBrandName()); +// assertThat(response.getProductLineStatus()).isEqualTo(productLine.getStatus()); +// } +// +// // 기존 데이터도 포함되어 있는지 확인 (샘플로 첫 번째 항목 확인) +// if (initialCount > 0) { +// ProductLine firstExistingProductLine = productLineRepository.selectAllProductLinesNotDeleted().get(0); +// ProductLineResponse firstResponse = responses.stream() +// .filter(r -> r.getProductLineStatus().equals(firstExistingProductLine.getProductLineId())) +// .findFirst() +// .orElseThrow(); +// +// assertThat(firstResponse.getProductLineStatus()).isEqualTo(firstExistingProductLine.getProductLineId()); +// assertThat(firstResponse.getName()).isEqualTo(firstExistingProductLine.getName()); +// assertThat(firstResponse.getPrice()).isEqualTo(firstExistingProductLine.getPrice()); +// assertThat(firstResponse.getProductLineStatus()).isEqualTo(firstExistingProductLine.getStatus()); +// } +// } +// +// @Test +// @DisplayName("특정 ProductLine ID로 조회 시 해당 ProductLine과 관련 Products가 반환된다.") +// void givenProductLineId_whenGetProductLineWithProducts_thenProductLineWithProductsIsReturned() throws Exception { +// // given +// ProductLine productLine = createSampleProductLine(); +// String url = PRODUCT_LINE_URL + "/" + productLine.getProductLineId(); +// +// // when +// ResultActions actions = mockMvc.perform(get(url) +// .contentType(MediaType.APPLICATION_JSON)); +// +// // then +// actions.andExpect(status().isOk()) +// .andExpect(jsonPath("$.id").value(productLine.getProductLineId())) +// .andDo(print()); +// +// String responseBody = actions.andReturn().getResponse().getContentAsString(); +// ProductLineWithProductsResponse response = objectMapper.readValue(responseBody, ProductLineWithProductsResponse.class); +// +// assertThat(response.getProductLineId()).isEqualTo(productLine.getProductLineId()); +// assertThat(response.getName()).isEqualTo(productLine.getName()); +// assertThat(response.getContent()).isEqualTo(productLine.getContent()); +// assertThat(response.getPrice()).isEqualTo(productLine.getPrice()); +// assertThat(response.getStatus()).isEqualTo(productLine.getStatus()); +// // 여기에 하위 제품(Products) 검증 로직 추가 +// } +// +// @Test +// @DisplayName("새로운 ProductLine 생성 요청 시 정상적으로 생성되고 반환된다.") +// void givenValidProductLineRequest_whenCreateProductLine_thenProductLineIsCreatedAndReturned() throws Exception { +// // given +// CreateProductLineRequest request = new CreateProductLineRequest( +// 1L, "New Product", "Description", 10000, ProductLineStatus.FOR_SALE); +// String content = objectMapper.writeValueAsString(request); +// +// // when +// ResultActions actions = mockMvc.perform(post(PRODUCT_LINE_URL) +// .contentType(MediaType.APPLICATION_JSON) +// .content(content)); +// +// // then +// actions.andExpect(status().isCreated()) +// .andExpect(header().exists("Location")) +// .andDo(print()); +// +// String locationHeader = actions.andReturn().getResponse().getHeader("Location"); +// Long productLineId = Long.parseLong(locationHeader.substring(locationHeader.lastIndexOf("/") + 1)); +// +// ProductLine createdProductLine = productLineRepository.selectByProductLineId(productLineId).orElseThrow(); +// +// assertThat(createdProductLine.getProductLineId()).isEqualTo(productLineId); +// assertThat(createdProductLine.getCategoryId()).isEqualTo(request.getCategoryId()); +// assertThat(createdProductLine.getName()).isEqualTo(request.getName()); +// assertThat(createdProductLine.getContent()).isEqualTo(request.getContent()); +// assertThat(createdProductLine.getPrice()).isEqualTo(request.getPrice()); +// assertThat(createdProductLine.getStatus()).isEqualTo(request.getStatus()); +// } +// +// @Test +// @DisplayName("기존 ProductLine 수정 요청 시 정상적으로 수정되는지 확인") +// void givenProductLineIdAndUpdateRequest_whenUpdateProductLine_thenProductLineIsUpdated() throws Exception { +// // given +// ProductLine originalProductLine = createSampleProductLine(); +// UpdateProductLineRequest request = new UpdateProductLineRequest( +// "Updated Product", "Updated Content", 100, ProductLineStatus.FOR_SALE); +// String content = objectMapper.writeValueAsString(request); +// String url = PRODUCT_LINE_URL + "/" + originalProductLine.getProductLineId(); +// +// // when +// ResultActions actions = mockMvc.perform(put(url) +// .contentType(MediaType.APPLICATION_JSON) +// .content(content)); +// +// // then +// actions.andExpect(status().isOk()) +// .andExpect(jsonPath("$.message").value("ProductLine updated successfully")) +// .andDo(print()); +// +// ProductLine updatedProductLine = productLineRepository.selectByProductLineId(originalProductLine.getProductLineId()).orElseThrow(); +// +// assertThat(updatedProductLine.getProductLineId()).isEqualTo(originalProductLine.getProductLineId()); +// assertThat(updatedProductLine.getName()).isEqualTo(request.getName()); +// assertThat(updatedProductLine.getContent()).isEqualTo(request.getContent()); +// assertThat(updatedProductLine.getPrice()).isEqualTo(request.getPrice()); +// assertThat(updatedProductLine.getStatus()).isEqualTo(request.getStatus()); +// } +// +// @Test +// @DisplayName("ProductLine 삭제 요청 시 정상적으로 삭제(soft delete)되는지 확인") +// void givenProductLineId_whenDeleteProductLine_thenProductLineIsSoftDeleted() throws Exception { +// // given +// ProductLine productLine = createSampleProductLine(); +// String url = PRODUCT_LINE_URL + "/" + productLine.getProductLineId(); +// +// // when +// ResultActions actions = mockMvc.perform(delete(url) +// .contentType(MediaType.APPLICATION_JSON)); +// +// // then +// actions.andExpect(status().isNoContent()); +// +// ProductLine deletedProductLine = productLineRepository.selectByProductLineId(productLine.getProductLineId()).orElseThrow(); +// assertThat(deletedProductLine.getDeletedAt()).isNotNull(); +// } +// +// private ProductLine createSampleProductLine() { +// CreateProductLineRequest request = new CreateProductLineRequest( +// 1L, "Sample Product", "Description", 10000, ProductLineStatus.FOR_SALE); +// Long productLineId = productLineService.createProductLine(request); +// return productLineRepository.selectByProductLineId(productLineId).orElseThrow(); +// } +// +// private List createSampleProductLines(int count) { +// List ids = new ArrayList<>(); +// for (int i = 0; i < count; i++) { +// ids.add(createSampleProductLine().getProductLineId()); +// } +// return ids; +// } +//}