Skip to content

Commit 64dead3

Browse files
authored
Merge pull request #212 from prgrms-be-devcourse/refactor/211-문제-태그-호출-api-수정
feat: 태그 응답에 난이도 목록 포함
2 parents ac221e9 + eb079ae commit 64dead3

5 files changed

Lines changed: 68 additions & 5 deletions

File tree

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
package com.back.domain.tag.tag.dto;
22

3-
public record TagResponse(String code, String label) {}
3+
import java.util.List;
4+
5+
public record TagResponse(String code, String label, List<String> difficulties) {}

src/main/java/com/back/domain/tag/tag/repository/TagRepository.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,31 @@
44
import java.util.Optional;
55

66
import org.springframework.data.jpa.repository.JpaRepository;
7+
import org.springframework.data.jpa.repository.Query;
78

9+
import com.back.domain.problem.problem.enums.DifficultyLevel;
810
import com.back.domain.tag.tag.entity.Tag;
911

1012
public interface TagRepository extends JpaRepository<Tag, Long> {
13+
interface TagDifficultyView {
14+
String getTagName();
15+
16+
DifficultyLevel getDifficulty();
17+
}
18+
1119
List<Tag> findAllByOrderByNameAsc();
1220

1321
Optional<Tag> findByName(String name);
22+
23+
@Query("""
24+
select t.name as tagName, p.difficulty as difficulty
25+
from ProblemTagConnect ptc
26+
join ptc.tag t
27+
join ptc.problem p
28+
where t.name is not null
29+
and trim(t.name) <> ''
30+
group by t.name, p.difficulty
31+
order by t.name asc
32+
""")
33+
List<TagDifficultyView> findTagDifficulties();
1434
}

src/main/java/com/back/domain/tag/tag/service/TagService.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package com.back.domain.tag.tag.service;
22

33
import java.util.List;
4+
import java.util.Map;
5+
import java.util.Set;
6+
import java.util.stream.Collectors;
47

58
import org.springframework.stereotype.Service;
69
import org.springframework.transaction.annotation.Transactional;
710

11+
import com.back.domain.problem.problem.enums.DifficultyLevel;
812
import com.back.domain.tag.tag.dto.TagResponse;
913
import com.back.domain.tag.tag.repository.TagRepository;
1014

@@ -15,14 +19,35 @@
1519
@Transactional(readOnly = true)
1620
public class TagService {
1721

22+
private static final List<DifficultyLevel> DIFFICULTY_ORDER =
23+
List.of(DifficultyLevel.EASY, DifficultyLevel.MEDIUM, DifficultyLevel.HARD);
24+
1825
private final TagRepository tagRepository;
1926

2027
public List<TagResponse> getTags() {
28+
Map<String, Set<DifficultyLevel>> difficultyByTag = tagRepository.findTagDifficulties().stream()
29+
.filter(row -> row.getTagName() != null && row.getDifficulty() != null)
30+
.filter(row -> !row.getTagName().trim().isBlank())
31+
.collect(Collectors.groupingBy(
32+
row -> row.getTagName().trim(),
33+
Collectors.mapping(TagRepository.TagDifficultyView::getDifficulty, Collectors.toSet())));
34+
2135
return tagRepository.findAllByOrderByNameAsc().stream()
2236
.map(tag -> tag.getName() == null ? null : tag.getName().trim())
2337
.filter(name -> name != null && !name.isBlank())
2438
.distinct()
25-
.map(name -> new TagResponse(name, name))
39+
.map(name -> new TagResponse(name, name, toDifficultyNames(difficultyByTag.get(name))))
40+
.toList();
41+
}
42+
43+
private List<String> toDifficultyNames(Set<DifficultyLevel> levels) {
44+
if (levels == null || levels.isEmpty()) {
45+
return List.of();
46+
}
47+
48+
return DIFFICULTY_ORDER.stream()
49+
.filter(levels::contains)
50+
.map(DifficultyLevel::name)
2651
.toList();
2752
}
2853
}

src/test/java/com/back/domain/tag/tag/controller/TagControllerTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ class TagControllerTest {
2121
@Test
2222
@DisplayName("태그 컨트롤러는 서비스 결과를 그대로 반환한다")
2323
void getTags_returnsServiceResult() {
24-
List<TagResponse> response = List.of(new TagResponse("array", "array"), new TagResponse("graph", "graph"));
24+
List<TagResponse> response = List.of(
25+
new TagResponse("array", "array", List.of("EASY")),
26+
new TagResponse("graph", "graph", List.of("MEDIUM", "HARD")));
2527

2628
when(tagService.getTags()).thenReturn(response);
2729

src/test/java/com/back/domain/tag/tag/service/TagServiceTest.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.junit.jupiter.api.DisplayName;
1010
import org.junit.jupiter.api.Test;
1111

12+
import com.back.domain.problem.problem.enums.DifficultyLevel;
1213
import com.back.domain.tag.tag.dto.TagResponse;
1314
import com.back.domain.tag.tag.entity.Tag;
1415
import com.back.domain.tag.tag.repository.TagRepository;
@@ -19,20 +20,33 @@ class TagServiceTest {
1920
private final TagService tagService = new TagService(tagRepository);
2021

2122
@Test
22-
@DisplayName("태그 목록 조회 시 code/label을 태그 이름으로 반환한다")
23+
@DisplayName("태그 목록 조회 시 code/label과 난이도 목록을 함께 반환한다")
2324
void getTags_returnsTagList() {
2425
Tag arrayTag = mock(Tag.class);
2526
Tag graphTag = mock(Tag.class);
2627
Tag blankTag = mock(Tag.class);
28+
TagRepository.TagDifficultyView arrayEasy = mock(TagRepository.TagDifficultyView.class);
29+
TagRepository.TagDifficultyView arrayHard = mock(TagRepository.TagDifficultyView.class);
30+
TagRepository.TagDifficultyView graphMedium = mock(TagRepository.TagDifficultyView.class);
2731

2832
when(arrayTag.getName()).thenReturn("array");
2933
when(graphTag.getName()).thenReturn("graph");
3034
when(blankTag.getName()).thenReturn(" ");
35+
when(arrayEasy.getTagName()).thenReturn("array");
36+
when(arrayEasy.getDifficulty()).thenReturn(DifficultyLevel.EASY);
37+
when(arrayHard.getTagName()).thenReturn("array");
38+
when(arrayHard.getDifficulty()).thenReturn(DifficultyLevel.HARD);
39+
when(graphMedium.getTagName()).thenReturn("graph");
40+
when(graphMedium.getDifficulty()).thenReturn(DifficultyLevel.MEDIUM);
3141

3242
when(tagRepository.findAllByOrderByNameAsc()).thenReturn(List.of(arrayTag, graphTag, blankTag));
43+
when(tagRepository.findTagDifficulties()).thenReturn(List.of(arrayEasy, arrayHard, graphMedium));
3344

3445
List<TagResponse> response = tagService.getTags();
3546

36-
assertThat(response).containsExactly(new TagResponse("array", "array"), new TagResponse("graph", "graph"));
47+
assertThat(response)
48+
.containsExactly(
49+
new TagResponse("array", "array", List.of("EASY", "HARD")),
50+
new TagResponse("graph", "graph", List.of("MEDIUM")));
3751
}
3852
}

0 commit comments

Comments
 (0)