diff --git a/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/ai/service/AiService.java b/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/ai/service/AiService.java index 7c3a820b..1ff5f460 100644 --- a/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/ai/service/AiService.java +++ b/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/ai/service/AiService.java @@ -6,11 +6,10 @@ import org.tuna.zoopzoop.backend.domain.datasource.ai.dto.AiExtractorDto; import org.tuna.zoopzoop.backend.domain.datasource.ai.dto.AnalyzeContentDto; import org.tuna.zoopzoop.backend.domain.datasource.ai.prompt.AiPrompt; +import org.tuna.zoopzoop.backend.domain.datasource.entity.Tag; import org.tuna.zoopzoop.backend.domain.datasource.repository.TagRepository; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.stream.Collectors; @Service @@ -28,17 +27,12 @@ public AiExtractorDto extract(String rawHtml) { return response; } - public AnalyzeContentDto analyzeContent(String content) { - // 모든 태그 가져오기 - List allTags = tagRepository.findAllTagNames(); - - // 중복 제거 (Set → 다시 List or String) - Set uniqueTags = new HashSet<>(allTags); - + public AnalyzeContentDto analyzeContent(String content, List tagList) { // JSON 배열 문자열로 변환 - String tags = uniqueTags.stream() - .map(tag -> "\"" + tag + "\"") // "tagName" - .collect(Collectors.joining(", ", "[", "]")); // ["tag1", "tag2"] + String tags = tagList.stream() + .map(Tag::getTagName) // 태그명만 추출 + .map(tagName -> "\"" + tagName + "\"") + .collect(Collectors.joining(", ", "[", "]")); AnalyzeContentDto response = chatClient.prompt() .user(AiPrompt.SUMMARY_TAG_CATEGORY.formatted(content, tags)) diff --git a/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/crawler/controller/CrawlerTestController.java b/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/crawler/controller/CrawlerTestController.java index a9088769..e6c28f50 100644 --- a/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/crawler/controller/CrawlerTestController.java +++ b/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/crawler/controller/CrawlerTestController.java @@ -8,6 +8,9 @@ import org.tuna.zoopzoop.backend.domain.datasource.crawler.service.CrawlerManagerService; import org.tuna.zoopzoop.backend.domain.datasource.dataprocessor.service.DataProcessorService; import org.tuna.zoopzoop.backend.domain.datasource.dto.DataSourceDto; +import org.tuna.zoopzoop.backend.domain.datasource.repository.TagRepository; + +import java.util.ArrayList; @RestController @RequestMapping("api/v1") @@ -15,9 +18,10 @@ public class CrawlerTestController { private final CrawlerManagerService crawlerManagerService; private final DataProcessorService dataProcessorService; + private final TagRepository tagRepository; @GetMapping("/crawl") public DataSourceDto crawl(@RequestParam String url) throws Exception { - return dataProcessorService.process(url); + return dataProcessorService.process(url, new ArrayList<>()); } } diff --git a/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/dataprocessor/service/DataProcessorService.java b/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/dataprocessor/service/DataProcessorService.java index b9354a6d..864f8c03 100644 --- a/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/dataprocessor/service/DataProcessorService.java +++ b/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/dataprocessor/service/DataProcessorService.java @@ -11,8 +11,10 @@ import org.tuna.zoopzoop.backend.domain.datasource.crawler.service.CrawlerManagerService; import org.tuna.zoopzoop.backend.domain.datasource.dto.ArticleData; import org.tuna.zoopzoop.backend.domain.datasource.dto.DataSourceDto; +import org.tuna.zoopzoop.backend.domain.datasource.entity.Tag; import java.io.IOException; +import java.util.List; @Service @RequiredArgsConstructor @@ -20,7 +22,7 @@ public class DataProcessorService { public final CrawlerManagerService crawlerManagerService; public final AiService aiService; - public DataSourceDto process(String url) throws IOException { + public DataSourceDto process(String url, List tagList) throws IOException { CrawlerResult result = crawlerManagerService.extractContent(url); ArticleData articleData = switch (result.type()) { @@ -47,7 +49,7 @@ yield new ArticleData( } }; - AnalyzeContentDto analyzeContentDto = aiService.analyzeContent(articleData.content()); + AnalyzeContentDto analyzeContentDto = aiService.analyzeContent(articleData.content(), tagList); return new DataSourceDto( articleData.title(), diff --git a/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/repository/TagRepository.java b/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/repository/TagRepository.java index 72a88027..24cadb08 100644 --- a/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/repository/TagRepository.java +++ b/src/main/java/org/tuna/zoopzoop/backend/domain/datasource/repository/TagRepository.java @@ -1,14 +1,9 @@ package org.tuna.zoopzoop.backend.domain.datasource.repository; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import org.tuna.zoopzoop.backend.domain.datasource.entity.Tag; -import java.util.List; - @Repository public interface TagRepository extends JpaRepository { - @Query("select t.tagName from Tag t") - List findAllTagNames(); } diff --git a/src/main/java/org/tuna/zoopzoop/backend/global/initData/BaseInitData.java b/src/main/java/org/tuna/zoopzoop/backend/global/initData/BaseInitData.java index 8e4e08a8..df82e460 100644 --- a/src/main/java/org/tuna/zoopzoop/backend/global/initData/BaseInitData.java +++ b/src/main/java/org/tuna/zoopzoop/backend/global/initData/BaseInitData.java @@ -8,9 +8,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Profile; import org.springframework.transaction.annotation.Transactional; -import org.tuna.zoopzoop.backend.domain.datasource.entity.Tag; import org.tuna.zoopzoop.backend.domain.datasource.repository.TagRepository; -import org.tuna.zoopzoop.backend.domain.datasource.ai.service.AiService; import org.tuna.zoopzoop.backend.domain.member.repository.MemberRepository; import org.tuna.zoopzoop.backend.domain.space.space.entity.Space; import org.tuna.zoopzoop.backend.domain.space.space.repository.SpaceRepository; @@ -40,20 +38,8 @@ public void initalizeData() { } - private final AiService aiService; - @Transactional public void initTagData() { - if (tagRepository.count() > 0) { - return; - } - - Tag tag1 = new Tag(null,"IT"); - Tag tag2 = new Tag(null, "자기소개"); - Tag tag3 = new Tag(null, "이름"); - tagRepository.save(tag1); - tagRepository.save(tag2); - tagRepository.save(tag3); } } diff --git a/src/test/java/org/tuna/zoopzoop/backend/domain/datasource/service/AiServiceTest.java b/src/test/java/org/tuna/zoopzoop/backend/domain/datasource/service/AiServiceTest.java new file mode 100644 index 00000000..ebefee04 --- /dev/null +++ b/src/test/java/org/tuna/zoopzoop/backend/domain/datasource/service/AiServiceTest.java @@ -0,0 +1,62 @@ +package org.tuna.zoopzoop.backend.domain.datasource.service; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.ai.chat.client.ChatClient; +import org.tuna.zoopzoop.backend.domain.datasource.ai.dto.AnalyzeContentDto; +import org.tuna.zoopzoop.backend.domain.datasource.ai.service.AiService; +import org.tuna.zoopzoop.backend.domain.datasource.entity.Category; +import org.tuna.zoopzoop.backend.domain.datasource.entity.Tag; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class AiServiceTest { + @Mock + private ChatClient chatClient; + + @Mock + private ChatClient.ChatClientRequestSpec requestSpec; + + @Mock + private ChatClient.CallResponseSpec responseSpec; + + + @InjectMocks + private AiService aiService; + + @Test + void analyzeContent_ShouldReturnMockedResponse() { + // given + String content = "테스트 본문"; + List tagList = List.of(new Tag("Java"), new Tag("Spring")); + + AnalyzeContentDto mockResponse = new AnalyzeContentDto( + "요약", + Category.IT, + List.of("Java", "Spring") + ); + + // 체인 mock 세팅 + when(chatClient.prompt()).thenReturn(requestSpec); + when(requestSpec.user(anyString())).thenReturn(requestSpec); + when(requestSpec.call()).thenReturn(responseSpec); + when(responseSpec.entity(AnalyzeContentDto.class)).thenReturn(mockResponse); + + // when + AnalyzeContentDto result = aiService.analyzeContent(content, tagList); + + // then + assertThat(result).isNotNull(); + assertThat(result.summary()).isEqualTo("요약"); + assertThat(result.tags()).containsExactly("Java", "Spring"); + assertThat(result.category()).isEqualTo(Category.IT); + } +} \ No newline at end of file