Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat : 커리큘럼 ID로 키워드들 조회 API 구현 #1472

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package wooteco.prolog.roadmap.application;

import static wooteco.prolog.common.exception.BadRequestCode.CURRICULUM_NOT_FOUND_EXCEPTION;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import wooteco.prolog.common.exception.BadRequestException;
import wooteco.prolog.roadmap.application.dto.KeywordsResponse;
import wooteco.prolog.roadmap.domain.Curriculum;
import wooteco.prolog.roadmap.domain.Keyword;
import wooteco.prolog.roadmap.domain.repository.CurriculumRepository;
import wooteco.prolog.roadmap.domain.repository.KeywordRepository;
import wooteco.prolog.session.domain.Session;
import wooteco.prolog.session.domain.repository.SessionRepository;

@RequiredArgsConstructor
@Transactional
@Service
public class RoadMapService {

private final CurriculumRepository curriculumRepository;
private final SessionRepository sessionRepository;
private final KeywordRepository keywordRepository;

@Transactional(readOnly = true)
public KeywordsResponse findAllKeywords(final Long curriculumId) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KeywordService에 넣지 않은 이유가 있을지 궁금합니다!

final Curriculum curriculum = curriculumRepository.findById(curriculumId)
.orElseThrow(() -> new BadRequestException(CURRICULUM_NOT_FOUND_EXCEPTION));

final Set<Long> sessionIds = sessionRepository.findAllByCurriculumId(curriculum.getId())
.stream()
.map(Session::getId)
.collect(Collectors.toSet());

final List<Keyword> keywords = keywordRepository.findBySessionIdIn(sessionIds);

return KeywordsResponse.createResponseWithChildren(keywords);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@ public static KeywordsResponse createResponse(final List<Keyword> keywords) {
.collect(Collectors.toList());
return new KeywordsResponse(keywordsResponse);
}

public static KeywordsResponse createResponseWithChildren(final List<Keyword> keywords) {
List<KeywordResponse> keywordsResponse = keywords.stream()
.filter(Keyword::isRoot)
.map(KeywordResponse::createWithAllChildResponse)
.collect(Collectors.toList());
return new KeywordsResponse(keywordsResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ private void validateKeywordParent(final Keyword parentKeyword) {
}
}

public boolean isRoot() {
return parent == null;
}

public Long getParentIdOrNull() {
if (parent == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package wooteco.prolog.roadmap.domain.repository;

import java.util.List;
import java.util.Set;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
Expand All @@ -17,4 +18,6 @@ public interface KeywordRepository extends JpaRepository<Keyword, Long> {
@Query("SELECT k FROM Keyword k "
+ "WHERE k.sessionId = :sessionId AND k.parent IS NULL")
List<Keyword> findBySessionIdAndParentIsNull(@Param("sessionId") Long sessionId);

List<Keyword> findBySessionIdIn(final Set<Long> sessionIds);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package wooteco.prolog.roadmap.ui;

import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import wooteco.prolog.roadmap.application.RoadMapService;
import wooteco.prolog.roadmap.application.dto.KeywordsResponse;

@RequiredArgsConstructor
@RestController
public class RoadmapController {

private final RoadMapService roadMapService;

@GetMapping("/roadmaps")
public KeywordsResponse findRoadMapKeyword(@RequestParam final Long curriculumId) {
return roadMapService.findAllKeywords(curriculumId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package wooteco.prolog.roadmap.application;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.when;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.DisplayName;
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 wooteco.prolog.roadmap.application.dto.KeywordsResponse;
import wooteco.prolog.roadmap.domain.Curriculum;
import wooteco.prolog.roadmap.domain.Keyword;
import wooteco.prolog.roadmap.domain.repository.CurriculumRepository;
import wooteco.prolog.roadmap.domain.repository.KeywordRepository;
import wooteco.prolog.session.domain.Session;
import wooteco.prolog.session.domain.repository.SessionRepository;

@ExtendWith(MockitoExtension.class)
class RoadMapServiceTest {

@Mock
private CurriculumRepository curriculumRepository;
@Mock
private SessionRepository sessionRepository;
@Mock
private KeywordRepository keywordRepository;
@InjectMocks
private RoadMapService roadMapService;

@Test
@DisplayName("curriculumId가 주어지면 해당 커리큘럼의 키워드들을 전부 조회할 수 있다.")
void findAllKeywords() {
//given
final Curriculum curriculum = new Curriculum(1L, "커리큘럼1");
final Session session = new Session(1L, curriculum.getId(), "세션1");
final List<Session> sessions = Arrays.asList(session);
final Keyword keyword = new Keyword(1L, "자바1", "자바 설명1", 1, 5, session.getId(),
null, Collections.emptySet());

when(curriculumRepository.findById(anyLong()))
.thenReturn(Optional.of(curriculum));

when(sessionRepository.findAllByCurriculumId(anyLong()))
.thenReturn(sessions);

when(keywordRepository.findBySessionIdIn(any()))
.thenReturn(Arrays.asList(keyword));

final KeywordsResponse expected = KeywordsResponse.createResponseWithChildren(Arrays.asList(keyword));

//when
final KeywordsResponse actual =
roadMapService.findAllKeywords(curriculum.getId());

//then
assertThat(actual)
.usingRecursiveComparison()
.isEqualTo(expected);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import javax.persistence.EntityManager;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import wooteco.prolog.roadmap.domain.Curriculum;
import wooteco.prolog.roadmap.domain.Keyword;
import wooteco.prolog.roadmap.domain.repository.CurriculumRepository;
import wooteco.prolog.roadmap.domain.repository.KeywordRepository;
import wooteco.prolog.session.domain.Session;
import wooteco.prolog.session.domain.repository.SessionRepository;
Expand All @@ -23,6 +27,8 @@ class KeywordRepositoryTest {
private SessionRepository sessionRepository;
@Autowired
private EntityManager em;
@Autowired
private CurriculumRepository curriculumRepository;

@Test
void 부모_키워드와_1뎁스까지의_자식_키워드를_함께_조회할_수_있다() {
Expand Down Expand Up @@ -105,7 +111,54 @@ class KeywordRepositoryTest {
sessionId);

// then
Assertions.assertThat(extractParentKeyword.size()).isEqualTo(1);
assertThat(extractParentKeyword.size()).isEqualTo(1);
}

@Test
@DisplayName("세션 ID 리스트로 키워드 리스트를 조회한다")
void findBySessionIdIn() {
//given
final Curriculum curriculum = curriculumRepository.save(new Curriculum("커리큘럼1"));

final Session session1 = sessionRepository.save(new Session(curriculum.getId(), "세션1"));
final Session session2 = sessionRepository.save(new Session(curriculum.getId(), "세션2"));
final Session session3 = sessionRepository.save(new Session(curriculum.getId(), "세션3"));
final Session session4 = sessionRepository.save(new Session(curriculum.getId(), "세션4"));
final Session session5 = sessionRepository.save(new Session(curriculum.getId(), "세션5"));

final Keyword keyword1 = keywordRepository.save(
Keyword.createKeyword("자바1", "자바 설명1", 1, 5, session1.getId(), null));
final Keyword keyword2 = keywordRepository.save(
Keyword.createKeyword("자바2", "자바 설명2", 2, 5, session1.getId(), keyword1));
final Keyword keyword3 = keywordRepository.save(
Keyword.createKeyword("자바3", "자바 설명3", 3, 5, session1.getId(), null));
final Keyword keyword4 = keywordRepository.save(
Keyword.createKeyword("자바4", "자바 설명4", 4, 5, session1.getId(), keyword3));
keywordRepository.save(
Keyword.createKeyword("자바5", "자바 설명5", 5, 5, session2.getId(), null));
keywordRepository.save(
Keyword.createKeyword("자바6", "자바 설명6", 6, 5, session2.getId(), keyword1));
keywordRepository.save(
Keyword.createKeyword("자바7", "자바 설명7", 7, 5, session2.getId(), null));
keywordRepository.save(
Keyword.createKeyword("자바8", "자바 설명8", 8, 5, session3.getId(), keyword2));
final Keyword keyword9 = keywordRepository.save(
Keyword.createKeyword("자바9", "자바 설명9", 9, 5, session4.getId(), keyword2));
final Keyword keyword10 = keywordRepository.save(
Keyword.createKeyword("자바10", "자바 설명10", 10, 5, session5.getId(), null));

final HashSet<Long> sessionIds = new HashSet<>(
Arrays.asList(session1.getId(), session4.getId(), session5.getId())
);

//when
final List<Keyword> keywords = keywordRepository.findBySessionIdIn(sessionIds);

//then
assertThat(keywords)
.usingRecursiveComparison()
.ignoringFields("id", "parent.id")
.isEqualTo(Arrays.asList(keyword1, keyword2, keyword3, keyword4, keyword9, keyword10));
}

private Keyword createKeywordParent(final Keyword keyword) {
Expand Down