diff --git a/src/main/java/com/back/domain/cocktail/controller/CocktailRecommendController.java b/src/main/java/com/back/domain/cocktail/controller/CocktailRecommendController.java index d8b877f4..3e5a1fb3 100644 --- a/src/main/java/com/back/domain/cocktail/controller/CocktailRecommendController.java +++ b/src/main/java/com/back/domain/cocktail/controller/CocktailRecommendController.java @@ -21,7 +21,7 @@ public class CocktailRecommendController { private final RecommendService recommendService; - // 상세페이지 추천 (DTO로 반환) + // 상세페이지 3개 칵테일 추천 (DTO로 반환) @Operation(summary = "상세페이지 유사 칵테일 추천", description = "현재 칵테일과 유사한 칵테일 최대 3개를 반환합니다.") @GetMapping("/related") public RsData> recommendRelated(@RequestParam Long cocktailId) { diff --git a/src/main/java/com/back/domain/cocktail/entity/Cocktail.java b/src/main/java/com/back/domain/cocktail/entity/Cocktail.java index d941ca65..a9420762 100644 --- a/src/main/java/com/back/domain/cocktail/entity/Cocktail.java +++ b/src/main/java/com/back/domain/cocktail/entity/Cocktail.java @@ -41,6 +41,7 @@ public class Cocktail { private String ingredient; + @Column(length = 1000) private String recipe; private String cocktailImgUrl; diff --git a/src/main/java/com/back/domain/cocktail/repository/CocktailRepository.java b/src/main/java/com/back/domain/cocktail/repository/CocktailRepository.java index 961be10f..0695c469 100644 --- a/src/main/java/com/back/domain/cocktail/repository/CocktailRepository.java +++ b/src/main/java/com/back/domain/cocktail/repository/CocktailRepository.java @@ -36,12 +36,10 @@ Page searchWithFilters(@Param("keyword") String keyword, @Param("types") List types, @Param("bases") List bases, Pageable pageable); - //유사칵테일 추천관련 - List findByAlcoholStrengthAndIdNot(AlcoholStrength strength, Long excludeId); - //유사칵테일 추천관련 - List findByCocktailTypeAndIdNot(CocktailType type, Long excludeId); - - //유사칵테일 추천관련 - List findByAlcoholBaseTypeAndIdNot(AlcoholBaseType baseType, Long excludeId); + List findByAlcoholStrengthAndAlcoholBaseTypeAndIdNot( + AlcoholStrength alcoholStrength, + AlcoholBaseType alcoholBaseType, + Long id + ); } diff --git a/src/main/java/com/back/domain/cocktail/service/CocktailService.java b/src/main/java/com/back/domain/cocktail/service/CocktailService.java index 06eba0de..1a36f507 100644 --- a/src/main/java/com/back/domain/cocktail/service/CocktailService.java +++ b/src/main/java/com/back/domain/cocktail/service/CocktailService.java @@ -78,7 +78,7 @@ public List searchAndFilter (CocktailSearchRequestDto int size = cocktailSearchRequestDto.getSize() != null && cocktailSearchRequestDto.getSize() > 0 ? cocktailSearchRequestDto.getSize() : DEFAULT_SIZE; - // searchWithFilters에서 조회한 결과값을 pageResult에 저장. + // searchAndFilters에서 조회한 결과값을 pageResult에 저장. Pageable pageable = PageRequest.of(page, size); // 빈 리스트(null 또는 [])는 null로 변환 diff --git a/src/main/java/com/back/domain/cocktail/service/RecommendService.java b/src/main/java/com/back/domain/cocktail/service/RecommendService.java index c0a6c96e..0d8e2681 100644 --- a/src/main/java/com/back/domain/cocktail/service/RecommendService.java +++ b/src/main/java/com/back/domain/cocktail/service/RecommendService.java @@ -6,10 +6,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Set; @Service @RequiredArgsConstructor @@ -21,24 +18,20 @@ public List recommendRelatedCocktails(Long cocktai Cocktail current = cocktailRepository.findById(cocktailId) .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 칵테일입니다.")); - // 3가지 조건으로 유사 칵테일 조회 - List byAlcoholStrength = cocktailRepository.findByAlcoholStrengthAndIdNot(current.getAlcoholStrength(), current.getId()); - List byCocktailType = cocktailRepository.findByCocktailTypeAndIdNot(current.getCocktailType(), current.getId()); - List byAlcoholBase = cocktailRepository.findByAlcoholBaseTypeAndIdNot(current.getAlcoholBaseType(), current.getId()); + // 알콜 강도와 베이스 타이이 같은 칵테일만 조회 + List related = cocktailRepository + .findByAlcoholStrengthAndAlcoholBaseTypeAndIdNot( + current.getAlcoholStrength(), + current.getAlcoholBaseType(), + current.getId() + ); - // 합치고 중복 제거 - Set combined = new LinkedHashSet<>(); - combined.addAll(byAlcoholStrength); - combined.addAll(byCocktailType); - combined.addAll(byAlcoholBase); - - List combinedList = new ArrayList<>(combined); - if (combinedList.size() > maxSize) { - combinedList = combinedList.subList(0, maxSize); + if (related.size() > maxSize) { + related = related.subList(0, maxSize); } // DTO로 변환 - return combinedList.stream() + return related.stream() .map(c -> new CocktailRecommendResponseDto( c.getId(), c.getCocktailNameKo(), diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index d29d56b7..28ebf512 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -1,8 +1,4 @@ spring: - sql: - init: - mode: always - data-locations: classpath:data-h2.sql # H2 Database 설정 datasource: driver-class-name: org.h2.Driver @@ -18,14 +14,21 @@ spring: # JPA 설정 jpa: + defer-datasource-initialization: true database-platform: org.hibernate.dialect.H2Dialect hibernate: - ddl-auto: update # 실행전 db_dev 파일 삭제 필요 + ddl-auto: create-drop # 개발용: 시작할 때 테이블 생성, 종료할 때 삭제 / db_dev 에러 방지용으로 update->create-drop 변경 properties: hibernate: format_sql: true show_sql: true + sql: + init: + mode: always # 항상 실행 + encoding: UTF-8 + data-locations: classpath:data-h2.sql + cloud: aws: region: diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index 0d0d39e9..b71450d6 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -1,8 +1,4 @@ spring: - sql: - init: - mode: always - data-locations: classpath:data-h2.sql datasource: url: jdbc:h2:mem:db_test;MODE=MySQL username: sa diff --git a/src/test/java/com/back/domain/cocktail/controller/CocktailControllerTest.java b/src/test/java/com/back/domain/cocktail/controller/CocktailControllerTest.java index 438dae72..2ac0de1e 100644 --- a/src/test/java/com/back/domain/cocktail/controller/CocktailControllerTest.java +++ b/src/test/java/com/back/domain/cocktail/controller/CocktailControllerTest.java @@ -5,14 +5,21 @@ import com.back.domain.cocktail.enums.AlcoholStrength; import com.back.domain.cocktail.enums.CocktailType; import com.back.domain.cocktail.repository.CocktailRepository; -import com.back.domain.cocktail.service.CocktailService; +import com.back.domain.user.service.UserService; +import com.back.global.rq.Rq; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; 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.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.transaction.annotation.Transactional; @@ -26,6 +33,10 @@ @ActiveProfiles("test") @SpringBootTest +@TestPropertySource(properties = { + "custom.cookie.secure=false", + "custom.cookie.same=Strict" +}) @AutoConfigureMockMvc(addFilters = false) @Transactional public class CocktailControllerTest { @@ -35,10 +46,6 @@ public class CocktailControllerTest { @Autowired private CocktailRepository cocktailRepository; - @Autowired - private CocktailService cocktailService; - - @Test @DisplayName("칵테일 단건 조회 - 로그인 없이 성공") void t1() throws Exception { @@ -130,4 +137,17 @@ void t4() throws Exception { .andExpect(jsonPath("$.message").value("success")) .andExpect(jsonPath("$.data").isArray()); } + + @TestConfiguration + static class TestConfig { + @Bean + public Rq rq() { + HttpServletRequest req = Mockito.mock(HttpServletRequest.class); + HttpServletResponse resp = Mockito.mock(HttpServletResponse.class); + UserService userService = Mockito.mock(UserService.class); + + return new Rq(req, resp, userService); + } + } + }