From f87bd95e197ce14e398f85622d80075124484f5d Mon Sep 17 00:00:00 2001 From: oliviarla Date: Wed, 27 Dec 2023 22:14:49 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=85=8C=EB=A7=88=EB=B3=84=20=ED=96=A5?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EC=B2=9C=20=EC=8B=9C=20=ED=96=A5=EC=88=98?= =?UTF-8?q?=20=EC=8A=A4=ED=86=A0=EB=A6=AC=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/http/dto/PerfumeThemeResponseDto.java | 4 +- .../dto/SimplePerfumeThemeResponseDto.java | 16 ++++++++ .../PerfumeQueryPersistenceAdapter.java | 7 ++-- .../port/in/dto/PerfumeThemeResult.java | 2 +- .../port/in/dto/SimplePerfumeThemeResult.java | 4 ++ .../port/out/PerfumeQueryRepository.java | 3 +- .../service/GetPerfumeThemeService.java | 4 +- .../in/http/PerfumeThemeControllerTest.java | 14 +++---- .../PerfumeQueryPersistenceAdapterTest.java | 39 +++++++++++++++++++ 9 files changed, 76 insertions(+), 17 deletions(-) create mode 100644 perfume-api/src/main/java/io/perfume/api/perfume/adapter/in/http/dto/SimplePerfumeThemeResponseDto.java create mode 100644 perfume-api/src/main/java/io/perfume/api/perfume/application/port/in/dto/SimplePerfumeThemeResult.java diff --git a/perfume-api/src/main/java/io/perfume/api/perfume/adapter/in/http/dto/PerfumeThemeResponseDto.java b/perfume-api/src/main/java/io/perfume/api/perfume/adapter/in/http/dto/PerfumeThemeResponseDto.java index b5fc4bed..d7696fee 100644 --- a/perfume-api/src/main/java/io/perfume/api/perfume/adapter/in/http/dto/PerfumeThemeResponseDto.java +++ b/perfume-api/src/main/java/io/perfume/api/perfume/adapter/in/http/dto/PerfumeThemeResponseDto.java @@ -4,12 +4,12 @@ import java.util.List; public record PerfumeThemeResponseDto( - String title, String content, String thumbnail, List perfumes) { + String title, String content, String thumbnail, List perfumes) { public static PerfumeThemeResponseDto from(PerfumeThemeResult perfumeThemeResult) { return new PerfumeThemeResponseDto( perfumeThemeResult.title(), perfumeThemeResult.content(), perfumeThemeResult.thumbnail(), - perfumeThemeResult.perfumes().stream().map(SimplePerfumeResponseDto::of).toList()); + perfumeThemeResult.perfumes().stream().map(SimplePerfumeThemeResponseDto::of).toList()); } } diff --git a/perfume-api/src/main/java/io/perfume/api/perfume/adapter/in/http/dto/SimplePerfumeThemeResponseDto.java b/perfume-api/src/main/java/io/perfume/api/perfume/adapter/in/http/dto/SimplePerfumeThemeResponseDto.java new file mode 100644 index 00000000..7a52d2be --- /dev/null +++ b/perfume-api/src/main/java/io/perfume/api/perfume/adapter/in/http/dto/SimplePerfumeThemeResponseDto.java @@ -0,0 +1,16 @@ +package io.perfume.api.perfume.adapter.in.http.dto; + +import io.perfume.api.perfume.application.port.in.dto.SimplePerfumeThemeResult; + +public record SimplePerfumeThemeResponseDto( + Long id, String name, String story, String thumbnail, String brandName) { + public static SimplePerfumeThemeResponseDto of( + SimplePerfumeThemeResult simplePerfumeThemeResult) { + return new SimplePerfumeThemeResponseDto( + simplePerfumeThemeResult.id(), + simplePerfumeThemeResult.name(), + simplePerfumeThemeResult.story(), + simplePerfumeThemeResult.thumbnail(), + simplePerfumeThemeResult.brandName()); + } +} diff --git a/perfume-api/src/main/java/io/perfume/api/perfume/adapter/out/persistence/perfume/PerfumeQueryPersistenceAdapter.java b/perfume-api/src/main/java/io/perfume/api/perfume/adapter/out/persistence/perfume/PerfumeQueryPersistenceAdapter.java index 81de1fad..be412508 100644 --- a/perfume-api/src/main/java/io/perfume/api/perfume/adapter/out/persistence/perfume/PerfumeQueryPersistenceAdapter.java +++ b/perfume-api/src/main/java/io/perfume/api/perfume/adapter/out/persistence/perfume/PerfumeQueryPersistenceAdapter.java @@ -17,6 +17,7 @@ import io.perfume.api.perfume.adapter.out.persistence.perfume.mapper.PerfumeMapper; import io.perfume.api.perfume.application.port.in.dto.PerfumeNameResult; import io.perfume.api.perfume.application.port.in.dto.SimplePerfumeResult; +import io.perfume.api.perfume.application.port.in.dto.SimplePerfumeThemeResult; import io.perfume.api.perfume.application.port.out.PerfumeQueryRepository; import io.perfume.api.perfume.domain.NotePyramid; import io.perfume.api.perfume.domain.Perfume; @@ -59,14 +60,14 @@ public Optional findPerfumeById(Long id) { } @Override - public List findPerfumesByIds(List ids) { + public List findPerfumesByIds(List ids) { return jpaQueryFactory .select( Projections.constructor( - SimplePerfumeResult.class, + SimplePerfumeThemeResult.class, perfumeJpaEntity.id, perfumeJpaEntity.name, - perfumeJpaEntity.concentration, + perfumeJpaEntity.story, brandEntity.name, fileJpaEntity.url)) .from(perfumeJpaEntity) diff --git a/perfume-api/src/main/java/io/perfume/api/perfume/application/port/in/dto/PerfumeThemeResult.java b/perfume-api/src/main/java/io/perfume/api/perfume/application/port/in/dto/PerfumeThemeResult.java index c3ae1d0d..e3ab52dd 100644 --- a/perfume-api/src/main/java/io/perfume/api/perfume/application/port/in/dto/PerfumeThemeResult.java +++ b/perfume-api/src/main/java/io/perfume/api/perfume/application/port/in/dto/PerfumeThemeResult.java @@ -3,4 +3,4 @@ import java.util.List; public record PerfumeThemeResult( - String title, String content, String thumbnail, List perfumes) {} + String title, String content, String thumbnail, List perfumes) {} diff --git a/perfume-api/src/main/java/io/perfume/api/perfume/application/port/in/dto/SimplePerfumeThemeResult.java b/perfume-api/src/main/java/io/perfume/api/perfume/application/port/in/dto/SimplePerfumeThemeResult.java new file mode 100644 index 00000000..ecf2b53a --- /dev/null +++ b/perfume-api/src/main/java/io/perfume/api/perfume/application/port/in/dto/SimplePerfumeThemeResult.java @@ -0,0 +1,4 @@ +package io.perfume.api.perfume.application.port.in.dto; + +public record SimplePerfumeThemeResult( + Long id, String name, String story, String brandName, String thumbnail) {} diff --git a/perfume-api/src/main/java/io/perfume/api/perfume/application/port/out/PerfumeQueryRepository.java b/perfume-api/src/main/java/io/perfume/api/perfume/application/port/out/PerfumeQueryRepository.java index 83fb989e..93683a20 100644 --- a/perfume-api/src/main/java/io/perfume/api/perfume/application/port/out/PerfumeQueryRepository.java +++ b/perfume-api/src/main/java/io/perfume/api/perfume/application/port/out/PerfumeQueryRepository.java @@ -4,6 +4,7 @@ import io.perfume.api.common.page.CustomSlice; import io.perfume.api.perfume.application.port.in.dto.PerfumeNameResult; import io.perfume.api.perfume.application.port.in.dto.SimplePerfumeResult; +import io.perfume.api.perfume.application.port.in.dto.SimplePerfumeThemeResult; import io.perfume.api.perfume.domain.NotePyramid; import io.perfume.api.perfume.domain.Perfume; import java.util.List; @@ -15,7 +16,7 @@ public interface PerfumeQueryRepository { Optional findPerfumeById(Long id); - List findPerfumesByIds(List ids); + List findPerfumesByIds(List ids); NotePyramid getNotePyramidByPerfume(Long perfumeId); diff --git a/perfume-api/src/main/java/io/perfume/api/perfume/application/service/GetPerfumeThemeService.java b/perfume-api/src/main/java/io/perfume/api/perfume/application/service/GetPerfumeThemeService.java index 1d28bc6f..e87547a7 100644 --- a/perfume-api/src/main/java/io/perfume/api/perfume/application/service/GetPerfumeThemeService.java +++ b/perfume-api/src/main/java/io/perfume/api/perfume/application/service/GetPerfumeThemeService.java @@ -5,7 +5,7 @@ import io.perfume.api.perfume.application.exception.PerfumeThemeNotFoundException; import io.perfume.api.perfume.application.port.in.GetPerfumeThemeUseCase; import io.perfume.api.perfume.application.port.in.dto.PerfumeThemeResult; -import io.perfume.api.perfume.application.port.in.dto.SimplePerfumeResult; +import io.perfume.api.perfume.application.port.in.dto.SimplePerfumeThemeResult; import io.perfume.api.perfume.application.port.out.PerfumeQueryRepository; import io.perfume.api.perfume.application.port.out.PerfumeThemeQueryRepository; import io.perfume.api.perfume.domain.PerfumeTheme; @@ -26,7 +26,7 @@ public PerfumeThemeResult getRecentTheme() { perfumeThemeQueryRepository .getRecentTheme() .orElseThrow(PerfumeThemeNotFoundException::new); - List perfumes = + List perfumes = perfumeQueryRepository.findPerfumesByIds(perfumeTheme.getPerfumeIds()); String thumbnail = findFileUseCase diff --git a/perfume-api/src/test/java/io/perfume/api/perfume/adapter/in/http/PerfumeThemeControllerTest.java b/perfume-api/src/test/java/io/perfume/api/perfume/adapter/in/http/PerfumeThemeControllerTest.java index f9fa59a8..9bd08843 100644 --- a/perfume-api/src/test/java/io/perfume/api/perfume/adapter/in/http/PerfumeThemeControllerTest.java +++ b/perfume-api/src/test/java/io/perfume/api/perfume/adapter/in/http/PerfumeThemeControllerTest.java @@ -11,8 +11,7 @@ import io.perfume.api.perfume.application.exception.PerfumeThemeNotFoundException; import io.perfume.api.perfume.application.port.in.GetPerfumeThemeUseCase; import io.perfume.api.perfume.application.port.in.dto.PerfumeThemeResult; -import io.perfume.api.perfume.application.port.in.dto.SimplePerfumeResult; -import io.perfume.api.perfume.domain.Concentration; +import io.perfume.api.perfume.application.port.in.dto.SimplePerfumeThemeResult; import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.BeforeEach; @@ -49,11 +48,11 @@ void setUp( @Test void getRecentTheme() throws Exception { - List perfumes = new ArrayList<>(); + List perfumes = new ArrayList<>(); for (int i = 1; i < 4; i++) { perfumes.add( - new SimplePerfumeResult( - (long) i, "No." + i, Concentration.EAU_DE_TOILETTE, "샤넬", "test-url.com/" + i)); + new SimplePerfumeThemeResult( + (long) i, "No." + i, "이 향수의 유래는 ...", "샤넬", "test-url.com/" + i)); } PerfumeThemeResult perfumeThemeResult = new PerfumeThemeResult( @@ -78,10 +77,9 @@ void getRecentTheme() throws Exception { fieldWithPath("thumbnail").description("테마 썸네일 URL"), fieldWithPath("perfumes[].id").description("테마에 포함된 향수 ID"), fieldWithPath("perfumes[].name").description("테마에 포함된 향수 이름"), + fieldWithPath("perfumes[].story").description("테마에 포함된 향수 스토리"), fieldWithPath("perfumes[].thumbnail").description("테마에 포함된 향수 썸네일 URL"), - fieldWithPath("perfumes[].brandName").description("테마에 포함된 향수 브랜드 이름"), - fieldWithPath("perfumes[].strength").description("테마에 포함된 향수 강도"), - fieldWithPath("perfumes[].duration").description("테마에 포함된 향수 지속력")))); + fieldWithPath("perfumes[].brandName").description("테마에 포함된 향수 브랜드 이름")))); } @Test diff --git a/perfume-api/src/test/java/io/perfume/api/perfume/adapter/out/persistence/perfume/PerfumeQueryPersistenceAdapterTest.java b/perfume-api/src/test/java/io/perfume/api/perfume/adapter/out/persistence/perfume/PerfumeQueryPersistenceAdapterTest.java index 7a32a950..81c86912 100644 --- a/perfume-api/src/test/java/io/perfume/api/perfume/adapter/out/persistence/perfume/PerfumeQueryPersistenceAdapterTest.java +++ b/perfume-api/src/test/java/io/perfume/api/perfume/adapter/out/persistence/perfume/PerfumeQueryPersistenceAdapterTest.java @@ -1,5 +1,6 @@ package io.perfume.api.perfume.adapter.out.persistence.perfume; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -19,6 +20,7 @@ import io.perfume.api.perfume.adapter.out.persistence.perfumeNote.PerfumeNoteEntity; import io.perfume.api.perfume.application.port.in.dto.PerfumeNameResult; import io.perfume.api.perfume.application.port.in.dto.SimplePerfumeResult; +import io.perfume.api.perfume.application.port.in.dto.SimplePerfumeThemeResult; import io.perfume.api.perfume.domain.Concentration; import io.perfume.api.perfume.domain.NotePyramid; import io.perfume.api.perfume.domain.Perfume; @@ -85,6 +87,43 @@ void findPerfumeById() { assertNull(resultPerfume.getDeletedAt()); } + @Test + void findPerfumesByIds() { + // given + List list = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + list.add( + PerfumeJpaEntity.builder() + .name("perfume" + i) + .story("story" + i) + .concentration(Concentration.EAU_DE_PARFUM) + .perfumeShopUrl("https://www.aesop.com/kr/p/fragrance/fresh/tacit-eau-de-parfum/") + .brandId(1L) + .categoryId(1L) + .thumbnailId(1L) + .build()); + } + List perfumeJpaEntities = perfumeJpaRepository.saveAll(list); + assertThat(perfumeJpaEntities).hasSize(5); + + // when + List perfumesByIds = + perfumeQueryPersistenceAdapter.findPerfumesByIds( + List.of(perfumeJpaEntities.get(0).getId(), perfumeJpaEntities.get(1).getId())); + + // then + assertThat(perfumesByIds).hasSize(2); + assertThat(perfumesByIds.get(0).id()).isEqualTo(perfumeJpaEntities.get(0).getId()); + assertThat(perfumesByIds.get(1).id()).isEqualTo(perfumeJpaEntities.get(1).getId()); + } + + @Test + void returnEmptyListIfFindPerfumesByNotExistingIds() { + List perfumesByIds = + perfumeQueryPersistenceAdapter.findPerfumesByIds(List.of(1L, 3L)); + assertThat(perfumesByIds).isEmpty(); + } + @Test void getNotePyramidIdsByPerfume() { // given