test #426

Merged
klaus merged 415 commits from test into main 2026-06-27 00:35:30 +00:00
3 changed files with 27 additions and 59 deletions
Showing only changes of commit 9c7b956fdc - Show all commits

View File

@@ -57,21 +57,6 @@ class HomeRecommendationController(
)
}
@GetMapping("/first-audio-contents")
fun getFirstAudioContents(
@RequestParam(defaultValue = "0") page: Int,
@RequestParam(defaultValue = "$DEFAULT_PAGE_SIZE") size: Int,
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
ApiResponse.ok(
homeRecommendationFacade.getFirstAudioContents(
requireMember(member),
normalizePage(page),
normalizeSize(size)
)
)
}
@GetMapping("/ai-characters")
fun getAiCharacters(
@RequestParam(defaultValue = "0") page: Int,

View File

@@ -143,24 +143,6 @@ class HomeRecommendationFacade(
}.getOrThrow()
}
fun getFirstAudioContents(member: Member, page: Int, size: Int): HomeRecommendationPageResponse<HomeFirstAudioContentItem> {
val startedAt = System.currentTimeMillis()
return runCatching {
val fetched = queryService.findFirstAudioContents(
now = LocalDateTime.now(),
offset = page.toOffset(size),
limit = size + 1,
memberId = member.id,
includeAdultContents = resolveAdultVisibility(member)
)
fetched.toPage(page, size) { it.toItem() }
}.onSuccess {
logPageSuccess("FIRST_AUDIO_CONTENT", member, page, size, it.items.size, System.currentTimeMillis() - startedAt)
}.onFailure { ex ->
logPageFailure("FIRST_AUDIO_CONTENT", member, page, size, startedAt, ex)
}.getOrThrow()
}
fun getAiCharacters(member: Member, page: Int, size: Int): HomeRecommendationPageResponse<HomeAiCharacterItem> {
val startedAt = System.currentTimeMillis()
return runCatching {

View File

@@ -324,24 +324,13 @@ class HomeRecommendationControllerTest @Autowired constructor(
includeAdultContents = Mockito.eq(false)
)
).thenThrow(IllegalStateException("debut page failed"))
Mockito.`when`(
failingQueryService.findFirstAudioContents(
now = Mockito.any(LocalDateTime::class.java) ?: LocalDateTime.MIN,
offset = Mockito.eq(0L),
limit = Mockito.eq(21),
memberId = Mockito.eq(member.id),
includeAdultContents = Mockito.eq(false)
)
).thenThrow(IllegalStateException("first audio page failed"))
Mockito.`when`(failingQueryService.findAiCharacterRecommendations(offset = 0L, limit = 21))
.thenThrow(IllegalStateException("ai page failed"))
assertThrows(IllegalStateException::class.java) { facade.getRecentDebutCreators(member, page = 0, size = 20) }
assertThrows(IllegalStateException::class.java) { facade.getFirstAudioContents(member, page = 0, size = 20) }
assertThrows(IllegalStateException::class.java) { facade.getAiCharacters(member, page = 0, size = 20) }
assertTrue(output.out.contains("section=DEBUT_CREATOR"))
assertTrue(output.out.contains("section=FIRST_AUDIO_CONTENT"))
assertTrue(output.out.contains("section=AI_CHARACTER"))
}
@@ -362,31 +351,43 @@ class HomeRecommendationControllerTest @Autowired constructor(
}
@Test
@DisplayName("첫 오디오/AI 캐릭터 전체보기도 같은 페이징 응답 형식을 사용한다")
@DisplayName("AI 캐릭터 전체보기도 같은 페이징 응답 형식을 사용한다")
fun shouldReturnPagedSectionsWithSameFormat() {
val member = saveMember("paged-section-viewer", MemberRole.USER)
entityManager.flush()
entityManager.clear()
for (path in listOf("/first-audio-contents", "/ai-characters")) {
mockMvc.perform(
get("/api/v2/home/recommendations$path")
.with(user(MemberAdapter(member)))
.param("page", "1")
.param("size", "10")
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.data.items").isArray)
.andExpect(jsonPath("$.data.page").value(1))
.andExpect(jsonPath("$.data.size").value(10))
.andExpect(jsonPath("$.data.hasNext").isBoolean)
}
mockMvc.perform(
get("/api/v2/home/recommendations/ai-characters")
.with(user(MemberAdapter(member)))
.param("page", "1")
.param("size", "10")
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.data.items").isArray)
.andExpect(jsonPath("$.data.page").value(1))
.andExpect(jsonPath("$.data.size").value(10))
.andExpect(jsonPath("$.data.hasNext").isBoolean)
}
@Test
@DisplayName("미배포 first-audio-contents 홈 하위 endpoint는 제거된다")
fun shouldNotExposeDeprecatedFirstAudioContentsEndpoint() {
val member = saveMember("home-viewer", MemberRole.USER)
entityManager.flush()
entityManager.clear()
mockMvc.perform(
get("/api/v2/home/recommendations/first-audio-contents")
.with(user(MemberAdapter(member)))
)
.andExpect(status().isNotFound)
}
@Test
@DisplayName("세부 전체보기 API는 비회원 요청을 거부한다")
fun shouldRejectAnonymousSectionPages() {
for (path in listOf("/lives", "/debut-creators", "/first-audio-contents", "/ai-characters")) {
for (path in listOf("/lives", "/debut-creators", "/ai-characters")) {
mockMvc.perform(get("/api/v2/home/recommendations$path"))
.andExpect(status().isUnauthorized)
}