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 @@ -33,6 +33,12 @@ public interface ReadPostRepository extends JpaRepository<ReadPost, Long> {
JOIN rp.post p
JOIN p.techBlog t
WHERE rp.user.id = :userId
AND rp.id IN (
SELECT MAX(rp2.id)
FROM ReadPost rp2
WHERE rp2.user.id = :userId
GROUP BY rp2.post.id
)
AND (:lastReadPostId IS NULL OR rp.id < :lastReadPostId)
ORDER BY rp.id DESC
""")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,29 @@ void getReadPosts_Success_Multiple() throws Exception {
.andExpect(jsonPath("$.data.readPosts[0].readAt").exists());
}

@Test
@DisplayName("읽은 게시글 목록 조회 성공 - 동일 포스트 중복 제거 확인")
void getReadPosts_Success_Deduplicated() throws Exception {
// Given - 동일한 포스트(testPost1)를 두 번 읽음
ReadPost readPost1 = ReadPost.create(testUser, testPost1, LocalDateTime.now().minusHours(2), 300);
ReadPost readPost2 = ReadPost.create(testUser, testPost1, LocalDateTime.now().minusHours(1), 400);
// 다른 포스트(testPost2)를 읽음
ReadPost readPost3 = ReadPost.create(testUser, testPost2, LocalDateTime.now(), 150);

readPostRepository.saveAll(List.of(readPost1, readPost2, readPost3));

// When & Then
mockMvc.perform(get("/api/v1/activities/read-posts")
.header("Authorization", "Bearer " + accessToken)
.param("size", "20"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.readPosts.length()").value(2)) // 3개가 아닌 2개여야 함
.andExpect(jsonPath("$.data.readPosts[0].postId").value(testPost2.getId()))
.andExpect(jsonPath("$.data.readPosts[1].postId").value(testPost1.getId()))
.andExpect(jsonPath("$.data.readPosts[1].readPostId").value(readPost2.getId())); // 더 최신 ID
}

@Test
@DisplayName("읽은 게시글 목록 조회 성공 - 북마크 상태 포함")
void getReadPosts_Success_WithBookmarks() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,35 @@ void saveDuplicateReadPost_Success() {
assertThat(all).allMatch(rp -> rp.getPost().getId().equals(testPost1.getId()));
assertThat(all).allMatch(rp -> rp.getUser().getId().equals(testUser.getId()));
}

@Test
@DisplayName("읽은 게시글 목록 조회 - 동일 포스트 중복 제거 및 최신순 정렬 확인")
void findReadPostsWithCursor_DeduplicateByPostId_Success() {
// Given
// 동일한 포스트(testPost1)를 두 번 읽음
ReadPost read1 = ReadPost.create(testUser, testPost1, LocalDateTime.now().minusHours(2), 100);
ReadPost read2 = ReadPost.create(testUser, testPost1, LocalDateTime.now().minusHours(1), 100);
// 다른 포스트(testPost2)를 읽음
ReadPost read3 = ReadPost.create(testUser, testPost2, LocalDateTime.now(), 100);

readPostRepository.saveAll(List.of(read1, read2, read3));

PageRequest pageRequest = PageRequest.of(0, 10);

// When
List<com.techfork.domain.activity.dto.ReadPostDto> result = readPostRepository.findReadPostsWithCursor(testUser.getId(), null, pageRequest);

// Then
// 1. 중복 제거 확인: 총 3개의 데이터 중 포스트 종류는 2개이므로 결과는 2개여야 함
assertThat(result).hasSize(2);

// 2. 최신 데이터 확인: testPost1에 대해서는 나중에 읽은 read2의 ID가 포함되어야 함
assertThat(result).extracting(com.techfork.domain.activity.dto.ReadPostDto::postId)
.containsExactlyInAnyOrder(testPost1.getId(), testPost2.getId());

// ID 기준으로 내림차순 정렬되었는지 확인 (read3 -> read2 순서)
// saveAll 후 ID를 가져오기 위해 리포지토리에서 다시 조회하거나, 순서만 확인
assertThat(result.get(0).postId()).isEqualTo(testPost2.getId()); // read3
assertThat(result.get(1).postId()).isEqualTo(testPost1.getId()); // read2
}
}
Loading