Skip to content
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
Expand Up @@ -21,6 +21,17 @@ public interface ContentRepository extends JpaRepository<Content, UUID> {
@Query("SELECT DISTINCT c FROM Content c JOIN c.contentTags ct WHERE ct.tag.id IN :tagIds AND c.isAvailable = true AND c.source.name <> 'YouTube' ORDER BY c.publishedAt DESC")
Page<Content> findByTagIdsAndIsAvailableTrue(@Param("tagIds") List<UUID> tagIds, Pageable pageable);

@Query("""
SELECT c FROM Content c
WHERE c.isAvailable = true AND c.source.name <> 'YouTube'
ORDER BY
CASE WHEN EXISTS (
SELECT ct FROM ContentTag ct WHERE ct.content = c AND ct.tag.id IN :tagIds
) THEN 0 ELSE 1 END,
c.publishedAt DESC
""")
Page<Content> findAllRankedByTagIds(@Param("tagIds") List<UUID> tagIds, Pageable pageable);

@Query("SELECT DISTINCT c FROM Content c LEFT JOIN c.contentTags ct LEFT JOIN ct.tag t " +
"WHERE c.isAvailable = true " +
"AND c.source.name <> 'YouTube' " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,7 @@ public ContentListResponse getFeed(UUID userId, Pageable pageable) {
if (tagIds.isEmpty()) {
page = contentRepository.findByIsAvailableTrueOrderByPublishedAtDesc(pageable);
} else {
page = contentRepository.findByTagIdsAndIsAvailableTrue(tagIds, pageable);
if (page.getTotalElements() == 0) {
page = contentRepository.findByIsAvailableTrueOrderByPublishedAtDesc(pageable);
}
page = contentRepository.findAllRankedByTagIds(tagIds, pageable);
}

List<ContentSummaryResponse> contents = page.getContent().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,14 @@ void getFeed_anonymous_skipsUserScopedQueries() {
}

@Test
@DisplayName("getFeed — 태그 있으면 태그 필터링된 콘텐츠 반환")
void getFeed_withUserTags_returnsFilteredFeed() {
@DisplayName("getFeed — 태그 있으면 랭킹 방식으로 전체 콘텐츠 반환 (관심 태그 우선)")
void getFeed_withUserTags_returnsRankedFeed() {
UserTag userTag = UserTag.builder()
.user(user)
.tag(Tag.builder().name("Spring").build())
.build();
given(userTagRepository.findByUser_Id(userId)).willReturn(List.of(userTag));
given(contentRepository.findByTagIdsAndIsAvailableTrue(any(), any()))
given(contentRepository.findAllRankedByTagIds(any(), any()))
.willReturn(new PageImpl<>(List.of(content)));
given(scrapRepository.existsByUser_IdAndContent_Id(any(), any())).willReturn(false);
given(likeRepository.existsByUser_IdAndContent_Id(any(), any())).willReturn(false);
Expand All @@ -151,21 +151,19 @@ void getFeed_withUserTags_returnsFilteredFeed() {
ContentListResponse response = contentService.getFeed(userId, PageRequest.of(0, 20));

assertThat(response.contents()).hasSize(1);
verify(contentRepository).findByTagIdsAndIsAvailableTrue(any(), any());
verify(contentRepository).findAllRankedByTagIds(any(), any());
verify(contentRepository, never()).findByIsAvailableTrueOrderByPublishedAtDesc(any());
}

@Test
@DisplayName("getFeed — 태그 필터 결과가 비면 전체 공개 글로 폴백")
void getFeed_tagFilterEmpty_fallsBackToAllAvailable() {
@DisplayName("getFeed — 관심 태그와 일치하는 글 없어도 전체 글 반환 (랭킹 방식)")
void getFeed_withUserTags_noTagMatch_stillReturnsAllContents() {
UserTag userTag = UserTag.builder()
.user(user)
.tag(Tag.builder().name("Rust").build())
.build();
given(userTagRepository.findByUser_Id(userId)).willReturn(List.of(userTag));
given(contentRepository.findByTagIdsAndIsAvailableTrue(any(), any()))
.willReturn(new PageImpl<>(List.of()));
given(contentRepository.findByIsAvailableTrueOrderByPublishedAtDesc(any()))
given(contentRepository.findAllRankedByTagIds(any(), any()))
.willReturn(new PageImpl<>(List.of(content)));
given(scrapRepository.existsByUser_IdAndContent_Id(any(), any())).willReturn(false);
given(likeRepository.existsByUser_IdAndContent_Id(any(), any())).willReturn(false);
Expand All @@ -174,8 +172,8 @@ void getFeed_tagFilterEmpty_fallsBackToAllAvailable() {
ContentListResponse response = contentService.getFeed(userId, PageRequest.of(0, 20));

assertThat(response.contents()).hasSize(1);
verify(contentRepository).findByTagIdsAndIsAvailableTrue(any(), any());
verify(contentRepository).findByIsAvailableTrueOrderByPublishedAtDesc(any());
verify(contentRepository).findAllRankedByTagIds(any(), any());
verify(contentRepository, never()).findByIsAvailableTrueOrderByPublishedAtDesc(any());
}

@Test
Expand Down
Loading