Skip to content
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
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.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.tuna.zoopzoop.backend.domain.datasource.entity.Tag;

import java.util.List;

@Repository
public interface TagRepository extends JpaRepository<Tag, Integer> {
@Query("""
select distinct t.tagName
from Tag t
where t.dataSource.folder.id = :folderId
""")
List<String> findDistinctTagNamesByFolderId(@Param("folderId") Integer folderId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@
import org.tuna.zoopzoop.backend.domain.archive.archive.repository.PersonalArchiveRepository;
import org.tuna.zoopzoop.backend.domain.archive.folder.entity.Folder;
import org.tuna.zoopzoop.backend.domain.archive.folder.repository.FolderRepository;
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.entity.Category;
import org.tuna.zoopzoop.backend.domain.datasource.entity.DataSource;
import org.tuna.zoopzoop.backend.domain.datasource.entity.Tag;
import org.tuna.zoopzoop.backend.domain.datasource.repository.DataSourceRepository;
import org.tuna.zoopzoop.backend.domain.datasource.repository.TagRepository;

import java.io.IOException;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
Expand All @@ -22,6 +27,8 @@ public class DataSourceService {
private final DataSourceRepository dataSourceRepository;
private final FolderRepository folderRepository;
private final PersonalArchiveRepository personalArchiveRepository;
private final TagRepository tagRepository;
private final DataProcessorService dataProcessorService;

/**
* 지정한 folder 위치에 자료 생성
Expand All @@ -35,23 +42,52 @@ public int createDataSource(int currentMemberId, String sourceUrl, Integer folde
folder = folderRepository.findById(folderId)
.orElseThrow(() -> new NoResultException("존재하지 않는 폴더입니다."));

DataSource ds = buildDataSource(sourceUrl, folder);
DataSource saved = dataSourceRepository.save(ds);
// 폴더 하위 자료 태그 수집(중복 X)
List<Tag> contextTags = collectDistinctTagsOfFolder(folder.getId());

DataSource ds = buildDataSource(folder, sourceUrl, contextTags);

// 4) 저장
final DataSource saved = dataSourceRepository.save(ds);
return saved.getId();
}

private DataSource buildDataSource(String sourceUrl, Folder folder) {
// 폴더 하위 태그 중복없이 list 반환
private List<Tag> collectDistinctTagsOfFolder(Integer folderId) {
List<String> names = tagRepository.findDistinctTagNamesByFolderId(folderId);

return names.stream()
.map(Tag::new)
.toList();
}

private DataSource buildDataSource(Folder folder, String sourceUrl, List<Tag> tagList) {
final DataSourceDto dataSourceDto;
try {
dataSourceDto = dataProcessorService.process(sourceUrl, tagList);
} catch (IOException e) {
throw new RuntimeException("자료 처리 중 오류가 발생했습니다.", e);
}

DataSource ds = new DataSource();
ds.setFolder(folder);
ds.setSourceUrl(sourceUrl);
ds.setTitle("자료 제목");
ds.setSource("www.examplesource.com");
ds.setSummary("설명");
ds.setImageUrl("www.example.com/img");
ds.setDataCreatedDate(LocalDate.now());
ds.setCategory(Category.IT);
ds.setSourceUrl(dataSourceDto.sourceUrl());
ds.setTitle(dataSourceDto.title());
ds.setSummary(dataSourceDto.summary());
ds.setDataCreatedDate(dataSourceDto.dataCreatedDate());
ds.setImageUrl(dataSourceDto.imageUrl());
ds.setSource(dataSourceDto.source());
ds.setCategory(dataSourceDto.category());
ds.setActive(true);

if (dataSourceDto.tags() != null) {
for (String tagName : dataSourceDto.tags()) {
Tag tag = new Tag(tagName);
tag.setDataSource(ds);
ds.getTags().add(tag);
}
}

return ds;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.tuna.zoopzoop.backend.domain.archive.folder.dto.FolderResponse;
import org.tuna.zoopzoop.backend.domain.archive.folder.entity.Folder;
import org.tuna.zoopzoop.backend.domain.archive.folder.repository.FolderRepository;
import org.tuna.zoopzoop.backend.domain.datasource.entity.Category;
import org.tuna.zoopzoop.backend.domain.datasource.dto.FolderFilesDto;
import org.tuna.zoopzoop.backend.domain.datasource.dto.FileSummary;
import org.tuna.zoopzoop.backend.domain.datasource.entity.DataSource;
Expand Down Expand Up @@ -272,7 +273,7 @@ void getFilesInFolderForPersonal_success() {
d1.setSourceUrl("http://src/a");
d1.setImageUrl("http://img/a");
d1.setTags(List.of(new Tag("tag1"), new Tag("tag2")));
d1.setCategory(org.tuna.zoopzoop.backend.domain.datasource.entity.Category.IT);
d1.setCategory(Category.IT);

DataSource d2 = new DataSource();
ReflectionTestUtils.setField(d2, "id", 11);
Expand All @@ -282,7 +283,7 @@ void getFilesInFolderForPersonal_success() {
d2.setSourceUrl("http://src/b");
d2.setImageUrl("http://img/b");
d2.setTags(List.of());
d2.setCategory(org.tuna.zoopzoop.backend.domain.datasource.entity.Category.SCIENCE);
d2.setCategory(Category.SCIENCE);

when(dataSourceRepository.findAllByFolder(folder)).thenReturn(List.of(d1, d2));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.*;
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.context.annotation.Primary;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.TestExecutionEvent;
import org.springframework.security.test.context.support.WithUserDetails;
Expand All @@ -15,11 +19,13 @@
import org.tuna.zoopzoop.backend.domain.archive.folder.entity.Folder;
import org.tuna.zoopzoop.backend.domain.archive.folder.service.FolderService;
import org.tuna.zoopzoop.backend.domain.archive.folder.repository.FolderRepository;
import org.tuna.zoopzoop.backend.domain.datasource.dataprocessor.service.DataProcessorService;
import org.tuna.zoopzoop.backend.domain.datasource.dto.*;
import org.tuna.zoopzoop.backend.domain.datasource.entity.Category;
import org.tuna.zoopzoop.backend.domain.datasource.entity.DataSource;
import org.tuna.zoopzoop.backend.domain.datasource.entity.Tag;
import org.tuna.zoopzoop.backend.domain.datasource.repository.DataSourceRepository;
import org.tuna.zoopzoop.backend.domain.datasource.repository.TagRepository;
import org.tuna.zoopzoop.backend.domain.member.enums.Provider;
import org.tuna.zoopzoop.backend.domain.member.repository.MemberRepository;
import org.tuna.zoopzoop.backend.domain.member.service.MemberService;
Expand All @@ -28,6 +34,8 @@
import java.util.List;

import static org.hamcrest.Matchers.*;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

Expand All @@ -37,7 +45,6 @@
@Transactional
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class DatasourceControllerTest {

@Autowired private MockMvc mockMvc;
@Autowired private ObjectMapper objectMapper;

Expand All @@ -47,13 +54,47 @@ class DatasourceControllerTest {
@Autowired private FolderRepository folderRepository;
@Autowired private DataSourceRepository dataSourceRepository;

private final String TEST_PROVIDER_KEY = "testUser_sc1111"; // WithUserDetails username -> "KAKAO:testUser_sc1111"
private final String TEST_PROVIDER_KEY = "testUser_sc1111";

private Integer testMemberId;
private Integer docsFolderId;
private Integer dataSourceId1;
private Integer dataSourceId2;

@TestConfiguration
static class StubConfig {
@Bean
@Primary
DataProcessorService stubDataProcessorService() throws Exception {
return new DataProcessorService(null, null) {
@Override
public DataSourceDto process(String url, List<Tag> tagList) {
return new DataSourceDto(
"테스트제목",
"테스트요약",
LocalDate.of(2025, 9, 1),
url,
"https://img.example/test.png",
"example.com",
Category.IT,
List.of("ML","Infra")
);
}
};
}

@Bean
@Primary
TagRepository stubTagRepository() {
TagRepository mock = Mockito.mock(TagRepository.class);

when(mock.findDistinctTagNamesByFolderId(anyInt()))
.thenReturn(java.util.List.of("AI", "Spring"));

return mock;
}
}

@BeforeAll
void beforeAll() {
try {
Expand Down Expand Up @@ -110,7 +151,6 @@ void beforeAll() {

@AfterAll
void afterAll() {
// 생성한 자료/폴더/멤버 삭제
try {
if (dataSourceId1 != null) dataSourceRepository.findById(dataSourceId1).ifPresent(dataSourceRepository::delete);
} catch (Exception ignored) {}
Expand Down
Loading