diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/adapter/in/web/HomeRecommendationController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/adapter/in/web/HomeRecommendationController.kt index 37cb631c..9f6b2e19 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/adapter/in/web/HomeRecommendationController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/adapter/in/web/HomeRecommendationController.kt @@ -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, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/application/HomeRecommendationFacade.kt b/src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/application/HomeRecommendationFacade.kt index ac8ab797..54648555 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/application/HomeRecommendationFacade.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/application/HomeRecommendationFacade.kt @@ -143,24 +143,6 @@ class HomeRecommendationFacade( }.getOrThrow() } - fun getFirstAudioContents(member: Member, page: Int, size: Int): HomeRecommendationPageResponse { - 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 { val startedAt = System.currentTimeMillis() return runCatching { diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/v2/api/home/HomeRecommendationControllerTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/v2/api/home/HomeRecommendationControllerTest.kt index dc151902..bc32db93 100644 --- a/src/test/kotlin/kr/co/vividnext/sodalive/v2/api/home/HomeRecommendationControllerTest.kt +++ b/src/test/kotlin/kr/co/vividnext/sodalive/v2/api/home/HomeRecommendationControllerTest.kt @@ -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) }