test #426
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user