feat(series-banner): 시리즈 배너를 언어별로 등록하고 노출한다
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
package kr.co.vividnext.sodalive.admin.content.series.banner
|
||||
|
||||
import com.amazonaws.services.s3.AmazonS3Client
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import kr.co.vividnext.sodalive.aws.s3.S3Uploader
|
||||
import kr.co.vividnext.sodalive.content.series.main.banner.ContentSeriesBannerService
|
||||
import kr.co.vividnext.sodalive.content.series.main.banner.SeriesBanner
|
||||
import kr.co.vividnext.sodalive.creator.admin.content.series.Series
|
||||
import kr.co.vividnext.sodalive.i18n.Lang
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.Mockito
|
||||
import org.springframework.data.domain.PageImpl
|
||||
import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.mock.web.MockMultipartFile
|
||||
import java.net.URL
|
||||
|
||||
class AdminContentSeriesBannerControllerTest {
|
||||
private val bannerService = Mockito.mock(ContentSeriesBannerService::class.java)
|
||||
private val amazonS3Client = Mockito.mock(AmazonS3Client::class.java)
|
||||
private val s3Uploader = S3Uploader(amazonS3Client)
|
||||
private val controller = AdminContentSeriesBannerController(
|
||||
bannerService = bannerService,
|
||||
s3Uploader = s3Uploader,
|
||||
langContext = LangContext(),
|
||||
messageSource = SodaMessageSource(),
|
||||
s3Bucket = "test-bucket",
|
||||
imageHost = "https://cdn.test"
|
||||
)
|
||||
|
||||
@Test
|
||||
fun shouldRegisterJapaneseBannerThroughAdminApi() {
|
||||
val image = MockMultipartFile("image", "banner.png", "image/png", "image".toByteArray())
|
||||
val registeredBanner = createBanner(id = 10L, lang = Lang.JA, imagePath = "")
|
||||
val updatedBanner = createBanner(id = 10L, lang = Lang.JA, imagePath = "")
|
||||
|
||||
Mockito.`when`(amazonS3Client.getUrl(Mockito.eq("test-bucket"), Mockito.anyString()))
|
||||
.thenAnswer { URL("https://cdn.test/${it.arguments[1]}") }
|
||||
|
||||
Mockito.`when`(
|
||||
bannerService.registerBanner(
|
||||
seriesId = 1L,
|
||||
imagePath = "",
|
||||
lang = Lang.JA
|
||||
)
|
||||
).thenReturn(registeredBanner)
|
||||
Mockito.doAnswer {
|
||||
updatedBanner.apply {
|
||||
imagePath = it.arguments[1] as String
|
||||
}
|
||||
}.`when`(bannerService).updateBanner(Mockito.eq(10L), Mockito.anyString(), Mockito.isNull())
|
||||
|
||||
val response = controller.registerBanner(
|
||||
image = image,
|
||||
requestString = "{\"seriesId\":1,\"lang\":\"ja\"}"
|
||||
)
|
||||
|
||||
assertTrue(response.success)
|
||||
assertEquals(10L, response.data?.id)
|
||||
assertTrue(response.data?.imagePath?.startsWith("https://cdn.test/series_banner/10/") == true)
|
||||
Mockito.verify(bannerService).registerBanner(1L, "", Lang.JA)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldDeserializeIso639LanguageCodeToLangEnum() {
|
||||
val request = ObjectMapper().readValue(
|
||||
"{\"seriesId\":1,\"lang\":\"en\"}",
|
||||
kr.co.vividnext.sodalive.admin.content.series.banner.dto.SeriesBannerRegisterRequest::class.java
|
||||
)
|
||||
|
||||
assertEquals(Lang.EN, request.lang)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldAppendBannerLanguageToSeriesTitleInBannerList() {
|
||||
val pageable = PageRequest.of(0, 20)
|
||||
val japaneseBanner = createBanner(id = 12L, lang = Lang.JA, imagePath = "banner/jp.png")
|
||||
|
||||
Mockito.`when`(bannerService.getActiveBanners(pageable))
|
||||
.thenReturn(PageImpl(listOf(japaneseBanner), pageable, 1))
|
||||
|
||||
val response = controller.getBannerList(page = 0, size = 20)
|
||||
|
||||
assertTrue(response.success)
|
||||
assertEquals("series-12 (일본어)", response.data?.content?.first()?.seriesTitle)
|
||||
}
|
||||
|
||||
private fun createBanner(id: Long, lang: Lang, imagePath: String): SeriesBanner {
|
||||
val series = Series(
|
||||
title = "series-$id",
|
||||
introduction = "introduction-$id",
|
||||
languageCode = "ko"
|
||||
)
|
||||
series.id = id
|
||||
|
||||
return SeriesBanner(
|
||||
imagePath = imagePath,
|
||||
series = series,
|
||||
sortOrder = 1,
|
||||
lang = lang
|
||||
).also {
|
||||
it.id = id
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package kr.co.vividnext.sodalive.content.series.main
|
||||
|
||||
import kr.co.vividnext.sodalive.content.ContentType
|
||||
import kr.co.vividnext.sodalive.content.series.ContentSeriesService
|
||||
import kr.co.vividnext.sodalive.content.series.GetSeriesListResponse
|
||||
import kr.co.vividnext.sodalive.content.series.main.banner.ContentSeriesBannerService
|
||||
import kr.co.vividnext.sodalive.content.series.main.banner.SeriesBanner
|
||||
import kr.co.vividnext.sodalive.creator.admin.content.series.Series
|
||||
import kr.co.vividnext.sodalive.i18n.Lang
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
|
||||
import kr.co.vividnext.sodalive.member.contentpreference.ViewerContentPreference
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.Mockito
|
||||
import org.springframework.data.domain.PageImpl
|
||||
import org.springframework.data.domain.PageRequest
|
||||
|
||||
class SeriesMainControllerTest {
|
||||
private val contentSeriesService = Mockito.mock(ContentSeriesService::class.java)
|
||||
private val bannerService = Mockito.mock(ContentSeriesBannerService::class.java)
|
||||
private val langContext = LangContext().apply { setLang(Lang.JA) }
|
||||
private val memberContentPreferenceService = Mockito.mock(MemberContentPreferenceService::class.java)
|
||||
private val controller = SeriesMainController(
|
||||
contentSeriesService = contentSeriesService,
|
||||
bannerService = bannerService,
|
||||
langContext = langContext,
|
||||
memberContentPreferenceService = memberContentPreferenceService,
|
||||
imageHost = "https://cdn.test"
|
||||
)
|
||||
|
||||
@Test
|
||||
fun shouldFetchOnlyRequestedLanguageBanners() {
|
||||
val member = createMember(id = 1L)
|
||||
val preference = ViewerContentPreference(
|
||||
countryCode = "KR",
|
||||
isAdultContentVisible = true,
|
||||
contentType = ContentType.ALL,
|
||||
isAdult = true
|
||||
)
|
||||
val pageable = PageRequest.of(0, 10)
|
||||
val japaneseBanner = SeriesBanner(
|
||||
imagePath = "banner/jp.png",
|
||||
series = createSeries(id = 10L),
|
||||
sortOrder = 1,
|
||||
lang = Lang.JA
|
||||
).also {
|
||||
it.id = 100L
|
||||
}
|
||||
|
||||
Mockito.`when`(memberContentPreferenceService.resolveForQuery(member)).thenReturn(preference)
|
||||
Mockito.`when`(bannerService.getDisplayBanners(pageable, Lang.JA))
|
||||
.thenReturn(PageImpl(listOf(japaneseBanner), pageable, 1))
|
||||
Mockito.`when`(
|
||||
contentSeriesService.getSeriesList(
|
||||
null,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
ContentType.ALL,
|
||||
member,
|
||||
0,
|
||||
20
|
||||
)
|
||||
).thenReturn(GetSeriesListResponse(totalCount = 0, items = emptyList()))
|
||||
Mockito.`when`(
|
||||
contentSeriesService.getRecommendSeriesList(
|
||||
true,
|
||||
ContentType.ALL,
|
||||
member
|
||||
)
|
||||
).thenReturn(emptyList())
|
||||
|
||||
val response = controller.fetchData(member)
|
||||
|
||||
assertTrue(response.success)
|
||||
assertEquals(1, response.data?.banners?.size)
|
||||
assertEquals("series-10", response.data?.banners?.first()?.seriesTitle)
|
||||
Mockito.verify(bannerService).getDisplayBanners(pageable, Lang.JA)
|
||||
Mockito.verify(bannerService, Mockito.never()).getActiveBanners(pageable)
|
||||
}
|
||||
|
||||
private fun createMember(id: Long): Member {
|
||||
return Member(
|
||||
email = "member-$id@test.com",
|
||||
password = "password",
|
||||
nickname = "member-$id"
|
||||
).also {
|
||||
it.id = id
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSeries(id: Long): Series {
|
||||
return Series(
|
||||
title = "series-$id",
|
||||
introduction = "introduction-$id",
|
||||
languageCode = "ja"
|
||||
).also {
|
||||
it.id = id
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package kr.co.vividnext.sodalive.content.series.main.banner
|
||||
|
||||
import kr.co.vividnext.sodalive.admin.content.series.AdminContentSeriesRepository
|
||||
import kr.co.vividnext.sodalive.creator.admin.content.series.Series
|
||||
import kr.co.vividnext.sodalive.i18n.Lang
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.Mockito
|
||||
import org.springframework.data.domain.PageImpl
|
||||
import org.springframework.data.domain.PageRequest
|
||||
|
||||
class ContentSeriesBannerServiceTest {
|
||||
private lateinit var bannerRepository: SeriesBannerRepository
|
||||
private lateinit var seriesRepository: AdminContentSeriesRepository
|
||||
private lateinit var service: ContentSeriesBannerService
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
bannerRepository = Mockito.mock(SeriesBannerRepository::class.java)
|
||||
seriesRepository = Mockito.mock(AdminContentSeriesRepository::class.java)
|
||||
service = ContentSeriesBannerService(
|
||||
bannerRepository = bannerRepository,
|
||||
seriesRepository = seriesRepository
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("일본어 배너 등록 요청은 JA 언어값으로 저장한다")
|
||||
fun shouldRegisterJapaneseBanner() {
|
||||
val series = createSeries(id = 1L)
|
||||
|
||||
Mockito.`when`(seriesRepository.findByIdAndActiveTrue(1L)).thenReturn(series)
|
||||
Mockito.`when`(bannerRepository.findMaxSortOrder()).thenReturn(2)
|
||||
Mockito.`when`(bannerRepository.save(Mockito.any(SeriesBanner::class.java))).thenAnswer { it.arguments[0] }
|
||||
|
||||
val banner = service.registerBanner(
|
||||
seriesId = 1L,
|
||||
imagePath = "banner/jp.png",
|
||||
lang = Lang.JA
|
||||
)
|
||||
|
||||
assertEquals(Lang.JA, banner.lang)
|
||||
assertEquals(3, banner.sortOrder)
|
||||
assertEquals("banner/jp.png", banner.imagePath)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("언어가 없는 배너 등록 요청은 KO로 저장한다")
|
||||
fun shouldRegisterKoreanBannerWhenLangIsMissing() {
|
||||
val series = createSeries(id = 2L)
|
||||
|
||||
Mockito.`when`(seriesRepository.findByIdAndActiveTrue(2L)).thenReturn(series)
|
||||
Mockito.`when`(bannerRepository.findMaxSortOrder()).thenReturn(null)
|
||||
Mockito.`when`(bannerRepository.save(Mockito.any(SeriesBanner::class.java))).thenAnswer { it.arguments[0] }
|
||||
|
||||
val banner = service.registerBanner(
|
||||
seriesId = 2L,
|
||||
imagePath = "banner/default.png",
|
||||
lang = null
|
||||
)
|
||||
|
||||
assertEquals(Lang.KO, banner.lang)
|
||||
assertEquals(1, banner.sortOrder)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("일본어 사용자는 일본어 배너만 조회한다")
|
||||
fun shouldReturnJapaneseBannersForJapaneseUser() {
|
||||
val pageable = PageRequest.of(0, 10)
|
||||
val japaneseBanner = SeriesBanner(
|
||||
imagePath = "banner/jp.png",
|
||||
series = createSeries(id = 3L),
|
||||
sortOrder = 1,
|
||||
lang = Lang.JA
|
||||
)
|
||||
val expectedPage = PageImpl(listOf(japaneseBanner), pageable, 1)
|
||||
|
||||
Mockito.`when`(bannerRepository.findByIsActiveTrueAndLangOrderBySortOrderAsc(Lang.JA, pageable))
|
||||
.thenReturn(expectedPage)
|
||||
|
||||
val actual = service.getDisplayBanners(pageable, Lang.JA)
|
||||
|
||||
assertEquals(expectedPage, actual)
|
||||
Mockito.verify(bannerRepository).findByIsActiveTrueAndLangOrderBySortOrderAsc(Lang.JA, pageable)
|
||||
Mockito.verify(bannerRepository, Mockito.never())
|
||||
.findByIsActiveTrueOrderBySortOrderAsc(pageable)
|
||||
}
|
||||
|
||||
private fun createSeries(id: Long): Series {
|
||||
return Series(
|
||||
title = "series-$id",
|
||||
introduction = "introduction-$id",
|
||||
languageCode = "ko"
|
||||
).also {
|
||||
it.id = id
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user