Skip to content

Commit

Permalink
Merge pull request #36 from Louie-03/BE-feature-GET_products_best_cat…
Browse files Browse the repository at this point in the history
…egory

[BE] 특정 카테고리의 베스트 음식 조회 기능 구현
  • Loading branch information
ku-kim committed Apr 25, 2022
2 parents 52dd9da + 1541eb2 commit a763171
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 15 deletions.
10 changes: 8 additions & 2 deletions BE/src/main/java/sidedish/com/controller/ProductsController.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import sidedish.com.controller.model.ProductDetailTypeResponse;
import sidedish.com.controller.model.ProductBasicTypeResponse;
import sidedish.com.controller.model.ProductDetailTypeResponse;
import sidedish.com.service.ProductsService;

@RestController
Expand All @@ -31,7 +31,13 @@ public List<ProductBasicTypeResponse> findProductsMealType(

@GetMapping("/{id}")
public ProductDetailTypeResponse findById(@PathVariable @Negative @NotNull Long id) {
return productsService.findById(id);
return productsService.findById(id);
}

@GetMapping("/best")
public List<ProductBasicTypeResponse> findAllByBestCategory(
@RequestParam String category) {
return productsService.findAllByBestCategory(category);
}

@GetMapping("/recommendation")
Expand Down
4 changes: 2 additions & 2 deletions BE/src/main/java/sidedish/com/domain/DiscountPolicy.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
public class DiscountPolicy {

private String policyName;
private float discountRate;
private long discountRate;

public long calculateFixedPrice(long originalPrice) {
return (long) (originalPrice * ((100 - discountRate) / 100));
return (long) (originalPrice * ((100 - discountRate) / (double) 100));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import sidedish.com.repository.entity.ProductEntity;

@Repository
public interface ProductsRepository extends CrudRepository<ProductEntity, Long> {

@Override
Expand All @@ -16,4 +14,6 @@ public interface ProductsRepository extends CrudRepository<ProductEntity, Long>
@Query("select id, discount_policy_id, delivery_policy_id, product_name, description, original_price, meal_category "
+ "from PRODUCT where meal_category = :mealType")
List<ProductEntity> findByMealType(@Param("mealType") String mealType);

List<ProductEntity> findAllByBestCategory(String category);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ public class DiscountPolicyEntity {
@Id
private final Long id;
private final String policyName;
private final float discountRate;
private final long discountRate;

@PersistenceConstructor
public DiscountPolicyEntity(Long id, String policyName, float discountRate) {
public DiscountPolicyEntity(Long id, String policyName, long discountRate) {
this.id = id;
this.policyName = policyName;
this.discountRate = discountRate;
Expand Down
28 changes: 21 additions & 7 deletions BE/src/main/java/sidedish/com/service/ProductsService.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,11 @@ public List<ProductBasicTypeResponse> findByMealType(String meal) {
discountPolicyRepository.findAll(),
deliveryPolicyRepository.findAll());

validProducts(products);
validateProducts(products);

return productsDtoMapper.toProductsBasicTypeResponseFromDomain(products);
}

private void validProducts(List<Product> products) {
if (products.isEmpty()) {
throw new NoSuchProductsException();
}
}

public ProductDetailTypeResponse findById(Long id) {

ProductEntity productEntity = productsRepository.findById(id).orElseThrow(() ->
Expand Down Expand Up @@ -81,6 +75,26 @@ public List<ProductBasicTypeResponse> recommend() {
return productsDtoMapper.toProductsBasicTypeResponseFromDomain(recommendationProducts);
}

public List<ProductBasicTypeResponse> findAllByBestCategory(String category) {
List<ProductEntity> productEntities =productsRepository.findAllByBestCategory(category);
List<DiscountPolicyEntity> discountPolicyEntities = discountPolicyRepository.findAll();
List<DeliveryPolicyEntity> deliveryPolicyEntities = deliveryPolicyRepository.findAll();

List<Product> products = domainEntityMapper.toDomainFromProductsEntity(productEntities,
discountPolicyEntities,
deliveryPolicyEntities);

validateProducts(products);

return productsDtoMapper.toProductsBasicTypeResponseFromDomain(products);
}

private void validateProducts(List<Product> products) {
if (products.isEmpty()) {
throw new NoSuchProductsException();
}
}

private List<ProductEntity> recommendProducts(List<ProductEntity> productEntities) {
Collections.shuffle(productEntities);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,61 @@ void setUp() {
.statusCode(HttpStatus.NOT_FOUND.value());
}

@Test
void 만약_category가_meat_경우_best_category가_meat_음식_조회_성공() {
given()
.accept(MediaType.APPLICATION_JSON_VALUE)

.when()
.get("/api/products/best?category=meat")

.then()
.statusCode(HttpStatus.OK.value())
.assertThat()
.body("[0].id", equalTo(1))
.body("[0].image", containsString("s3"))
.body("[0].productName", equalTo("오리주물럭"))
.body("[0].description", equalTo("감칠맛 나는 매콤한 양념"))
.body("[0].event", equalTo("런칭특가"))
.body("[0].fixedPrice", equalTo(14220))
.body("[0].originalPrice", equalTo(15800))
.body("[1].id", equalTo(3))
.body("[1].image", containsString("s3"))
.body("[1].productName", equalTo("소갈비찜"))
.body("[1].description", equalTo("촉촉하게 밴 양념이 일품"))
.body("[1].event", equalTo("이벤트특가"))
.body("[1].fixedPrice", equalTo(23120))
.body("[1].originalPrice", equalTo(28900))
.body("[2].id", equalTo(5))
.body("[2].image", containsString("s3"))
.body("[2].productName", equalTo("한돈 돼지 김치찌개"))
.body("[2].description", equalTo("김치찌개에는 역시 돼지고기"))
.body("[2].event", equalTo("이벤트특가"))
.body("[2].fixedPrice", equalTo(7440))
.body("[2].originalPrice", equalTo(9300));
}

@Test
void 만약_파라미터인_category_입력하지_않은_경우_베스트_카테고리_음식_조회_실패() {
given()
.accept(MediaType.APPLICATION_JSON_VALUE)

.when()
.get("/api/products/best")

.then()
.statusCode(HttpStatus.BAD_REQUEST.value());
}

@Test
void 만약_category_값이_유효하지_않는_경우_조회_실패() {
given()
.accept(MediaType.APPLICATION_JSON_VALUE)

.when()
.get("/api/products/best?category=abc")

.then()
.statusCode(HttpStatus.NOT_FOUND.value());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ class ProductsControllerTest {
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
}

@Test
void 만약_category가_meat_경우_베스트_음식__meat_타입_조회_성공() throws Exception {
given(productsService.findAllByBestCategory("meat"))
.willReturn(createProductsMealTypeResponse());

ResultActions perform = mockMvc.perform(get("/api/products/best?category=meat"));

perform
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
}

private List<ProductBasicTypeResponse> createProductsMealTypeResponse() {
List<Product> products = new ArrayList<>();

Expand All @@ -78,4 +90,6 @@ private List<ProductBasicTypeResponse> createProductsMealTypeResponse() {

return productsDtoMapper.toProductsBasicTypeResponseFromDomain(products);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,68 @@ void It_returns_product() {
}
}

@Nested
@DisplayName("findAllByBestCategory(String Category) 메서드")
class Describe_findAllByBestCategory {

@Nested
@DisplayName("만약 category가 유효한 meat로 주어진다면")
class Context_with__category_is_meat {

@Test
@DisplayName("category가 meat인 모든 Product의 List를 반환한다")
void It_returns_products_best_category_meat() {
List<ProductEntity> result = productsRepository.findAllByBestCategory("meat");
ProductEntity sut = result.get(0);

assertThat(result.size()).isEqualTo(3);
assertThat(sut.getBestCategory()).isEqualTo("meat");
}
}

@Nested
@DisplayName("만약 category가 유효한 easy로 주어진다면")
class Context_with__category_is_easy {

@Test
@DisplayName("category가 easy인 모든 Product의 List를 반환한다")
void It_returns_products_best_category_easy() {
List<ProductEntity> result = productsRepository.findAllByBestCategory("easy");
ProductEntity sut = result.get(0);

assertThat(result.size()).isEqualTo(3);
assertThat(sut.getBestCategory()).isEqualTo("easy");
}
}

@Nested
@DisplayName("만약 category가 유효한 season으로 주어진다면")
class Context_with__category_is_season {

@Test
@DisplayName("category가 season인 모든 Product의 List를 반환한다")
void It_returns_products_best_category_season() {
List<ProductEntity> result = productsRepository.findAllByBestCategory("season");
ProductEntity sut = result.get(0);

assertThat(result.size()).isEqualTo(2);
assertThat(sut.getBestCategory()).isEqualTo("season");
}
}

@Nested
@DisplayName("만약 category가 유효한 kids으로 주어진다면")
class Context_with__category_is_kids {

@Test
@DisplayName("category가 kids인 모든 Product의 List를 반환한다")
void It_returns_products_best_category_kids() {
List<ProductEntity> result = productsRepository.findAllByBestCategory("kids");
ProductEntity sut = result.get(0);

assertThat(result.size()).isEqualTo(2);
assertThat(sut.getBestCategory()).isEqualTo("kids");
}
}
}
}

0 comments on commit a763171

Please sign in to comment.