test #428
@@ -0,0 +1,113 @@
|
|||||||
|
package kr.co.vividnext.sodalive.admin.content.series.banner
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.series.genre.SeriesGenre
|
||||||
|
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.member.Member
|
||||||
|
import kr.co.vividnext.sodalive.member.MemberRole
|
||||||
|
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
|
||||||
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user
|
||||||
|
import org.springframework.test.annotation.DirtiesContext
|
||||||
|
import org.springframework.test.context.ContextConfiguration
|
||||||
|
import org.springframework.test.web.servlet.MockMvc
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
|
||||||
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
|
||||||
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate
|
||||||
|
import javax.persistence.EntityManager
|
||||||
|
|
||||||
|
@SpringBootTest(
|
||||||
|
properties = [
|
||||||
|
"cloud.aws.cloud-front.host=https://cdn.test",
|
||||||
|
"spring.datasource.url=jdbc:h2:mem:admin-series-banner-controller-integration;" +
|
||||||
|
"MODE=MySQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=VALUE;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
@ContextConfiguration(initializers = [EmbeddedRedisInitializer::class])
|
||||||
|
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
|
||||||
|
class AdminContentSeriesBannerControllerIntegrationTest @Autowired constructor(
|
||||||
|
private val mockMvc: MockMvc,
|
||||||
|
private val entityManager: EntityManager,
|
||||||
|
private val transactionTemplate: TransactionTemplate
|
||||||
|
) {
|
||||||
|
@Test
|
||||||
|
@DisplayName("관리자 시리즈 배너 목록 API는 OSIV off 환경에서 lazy 초기화 예외 없이 응답한다")
|
||||||
|
fun shouldReturnAdminSeriesBannerListWhenOpenInViewIsDisabled() {
|
||||||
|
createBannerFixture()
|
||||||
|
|
||||||
|
mockMvc.perform(
|
||||||
|
get("/admin/audio-content/series/banner/list")
|
||||||
|
.param("page", "0")
|
||||||
|
.param("size", "20")
|
||||||
|
.with(user("admin").roles("ADMIN"))
|
||||||
|
)
|
||||||
|
.andExpect(status().isOk)
|
||||||
|
.andExpect(jsonPath("$.success").value(true))
|
||||||
|
.andExpect(jsonPath("$.data.totalCount").value(1))
|
||||||
|
.andExpect(jsonPath("$.data.content[0].seriesTitle").value("series-admin-banner (일본어)"))
|
||||||
|
.andExpect(jsonPath("$.data.content[0].imagePath").value("https://cdn.test/banner/jp.png"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("관리자 시리즈 배너 상세 API는 OSIV off 환경에서 lazy 초기화 예외 없이 응답한다")
|
||||||
|
fun shouldReturnAdminSeriesBannerDetailWhenOpenInViewIsDisabled() {
|
||||||
|
val bannerId = createBannerFixture()
|
||||||
|
|
||||||
|
mockMvc.perform(
|
||||||
|
get("/admin/audio-content/series/banner/{bannerId}", bannerId)
|
||||||
|
.with(user("admin").roles("ADMIN"))
|
||||||
|
)
|
||||||
|
.andExpect(status().isOk)
|
||||||
|
.andExpect(jsonPath("$.success").value(true))
|
||||||
|
.andExpect(jsonPath("$.data.id").value(bannerId))
|
||||||
|
.andExpect(jsonPath("$.data.seriesTitle").value("series-admin-banner"))
|
||||||
|
.andExpect(jsonPath("$.data.imagePath").value("https://cdn.test/banner/jp.png"))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createBannerFixture(): Long {
|
||||||
|
return transactionTemplate.execute {
|
||||||
|
val creator = Member(
|
||||||
|
email = "admin-series-banner-controller@test.com",
|
||||||
|
password = "password",
|
||||||
|
nickname = "admin-series-banner-creator",
|
||||||
|
role = MemberRole.CREATOR
|
||||||
|
)
|
||||||
|
entityManager.persist(creator)
|
||||||
|
|
||||||
|
val genre = SeriesGenre(genre = "admin-series-banner-genre")
|
||||||
|
entityManager.persist(genre)
|
||||||
|
|
||||||
|
val series = Series(
|
||||||
|
title = "series-admin-banner",
|
||||||
|
introduction = "introduction",
|
||||||
|
languageCode = "ko"
|
||||||
|
).apply {
|
||||||
|
member = creator
|
||||||
|
this.genre = genre
|
||||||
|
}
|
||||||
|
entityManager.persist(series)
|
||||||
|
|
||||||
|
val banner = SeriesBanner(
|
||||||
|
imagePath = "banner/jp.png",
|
||||||
|
series = series,
|
||||||
|
sortOrder = 1,
|
||||||
|
lang = Lang.JA
|
||||||
|
)
|
||||||
|
entityManager.persist(
|
||||||
|
banner
|
||||||
|
)
|
||||||
|
|
||||||
|
entityManager.flush()
|
||||||
|
val bannerId = banner.id!!
|
||||||
|
entityManager.clear()
|
||||||
|
bannerId
|
||||||
|
}!!
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@ package kr.co.vividnext.sodalive.admin.content.series.banner
|
|||||||
|
|
||||||
import com.amazonaws.services.s3.AmazonS3Client
|
import com.amazonaws.services.s3.AmazonS3Client
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.series.banner.dto.SeriesBannerListPageResponse
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.series.banner.dto.SeriesBannerResponse
|
||||||
import kr.co.vividnext.sodalive.aws.s3.S3Uploader
|
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.ContentSeriesBannerService
|
||||||
import kr.co.vividnext.sodalive.content.series.main.banner.SeriesBanner
|
import kr.co.vividnext.sodalive.content.series.main.banner.SeriesBanner
|
||||||
@@ -13,7 +15,6 @@ import org.junit.jupiter.api.Assertions.assertEquals
|
|||||||
import org.junit.jupiter.api.Assertions.assertTrue
|
import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.mockito.Mockito
|
import org.mockito.Mockito
|
||||||
import org.springframework.data.domain.PageImpl
|
|
||||||
import org.springframework.data.domain.PageRequest
|
import org.springframework.data.domain.PageRequest
|
||||||
import org.springframework.mock.web.MockMultipartFile
|
import org.springframework.mock.web.MockMultipartFile
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
@@ -35,7 +36,12 @@ class AdminContentSeriesBannerControllerTest {
|
|||||||
fun shouldRegisterJapaneseBannerThroughAdminApi() {
|
fun shouldRegisterJapaneseBannerThroughAdminApi() {
|
||||||
val image = MockMultipartFile("image", "banner.png", "image/png", "image".toByteArray())
|
val image = MockMultipartFile("image", "banner.png", "image/png", "image".toByteArray())
|
||||||
val registeredBanner = createBanner(id = 10L, lang = Lang.JA, imagePath = "")
|
val registeredBanner = createBanner(id = 10L, lang = Lang.JA, imagePath = "")
|
||||||
val updatedBanner = createBanner(id = 10L, lang = Lang.JA, imagePath = "")
|
val updatedResponse = SeriesBannerResponse(
|
||||||
|
id = 10L,
|
||||||
|
imagePath = "https://cdn.test/series_banner/10/banner.png",
|
||||||
|
seriesId = 10L,
|
||||||
|
seriesTitle = "series-10"
|
||||||
|
)
|
||||||
|
|
||||||
Mockito.`when`(amazonS3Client.getUrl(Mockito.eq("test-bucket"), Mockito.anyString()))
|
Mockito.`when`(amazonS3Client.getUrl(Mockito.eq("test-bucket"), Mockito.anyString()))
|
||||||
.thenAnswer { URL("https://cdn.test/${it.arguments[1]}") }
|
.thenAnswer { URL("https://cdn.test/${it.arguments[1]}") }
|
||||||
@@ -47,11 +53,14 @@ class AdminContentSeriesBannerControllerTest {
|
|||||||
lang = Lang.JA
|
lang = Lang.JA
|
||||||
)
|
)
|
||||||
).thenReturn(registeredBanner)
|
).thenReturn(registeredBanner)
|
||||||
Mockito.doAnswer {
|
Mockito.`when`(
|
||||||
updatedBanner.apply {
|
bannerService.updateBannerResponse(
|
||||||
imagePath = it.arguments[1] as String
|
bannerId = eqLong(10L),
|
||||||
}
|
imagePath = anyStringValue(),
|
||||||
}.`when`(bannerService).updateBanner(Mockito.eq(10L), Mockito.anyString(), Mockito.isNull())
|
seriesId = nullLongValue(),
|
||||||
|
imageHost = eqString("https://cdn.test")
|
||||||
|
)
|
||||||
|
).thenReturn(updatedResponse)
|
||||||
|
|
||||||
val response = controller.registerBanner(
|
val response = controller.registerBanner(
|
||||||
image = image,
|
image = image,
|
||||||
@@ -60,8 +69,52 @@ class AdminContentSeriesBannerControllerTest {
|
|||||||
|
|
||||||
assertTrue(response.success)
|
assertTrue(response.success)
|
||||||
assertEquals(10L, response.data?.id)
|
assertEquals(10L, response.data?.id)
|
||||||
assertTrue(response.data?.imagePath?.startsWith("https://cdn.test/series_banner/10/") == true)
|
assertEquals("https://cdn.test/series_banner/10/banner.png", response.data?.imagePath)
|
||||||
Mockito.verify(bannerService).registerBanner(1L, "", Lang.JA)
|
Mockito.verify(bannerService).registerBanner(1L, "", Lang.JA)
|
||||||
|
Mockito.verify(bannerService).updateBannerResponse(
|
||||||
|
bannerId = eqLong(10L),
|
||||||
|
imagePath = anyStringValue(),
|
||||||
|
seriesId = nullLongValue(),
|
||||||
|
imageHost = eqString("https://cdn.test")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldDelegateUpdateBannerResponseToService() {
|
||||||
|
val image = MockMultipartFile("image", "banner.png", "image/png", "image".toByteArray())
|
||||||
|
val serviceResponse = SeriesBannerResponse(
|
||||||
|
id = 10L,
|
||||||
|
imagePath = "https://cdn.test/series_banner/10/banner.png",
|
||||||
|
seriesId = 20L,
|
||||||
|
seriesTitle = "series-20"
|
||||||
|
)
|
||||||
|
|
||||||
|
Mockito.`when`(amazonS3Client.getUrl(Mockito.eq("test-bucket"), Mockito.anyString()))
|
||||||
|
.thenAnswer { URL("https://cdn.test/${it.arguments[1]}") }
|
||||||
|
Mockito.`when`(bannerService.getBannerById(10L)).thenReturn(createBanner(id = 10L, lang = Lang.JA, imagePath = "old.png"))
|
||||||
|
Mockito.`when`(
|
||||||
|
bannerService.updateBannerResponse(
|
||||||
|
bannerId = eqLong(10L),
|
||||||
|
imagePath = anyStringValue(),
|
||||||
|
seriesId = eqLong(20L),
|
||||||
|
imageHost = eqString("https://cdn.test")
|
||||||
|
)
|
||||||
|
).thenReturn(serviceResponse)
|
||||||
|
|
||||||
|
val response = controller.updateBanner(
|
||||||
|
image = image,
|
||||||
|
requestString = "{\"bannerId\":10,\"seriesId\":20}"
|
||||||
|
)
|
||||||
|
|
||||||
|
assertTrue(response.success)
|
||||||
|
assertEquals("series-20", response.data?.seriesTitle)
|
||||||
|
Mockito.verify(bannerService).getBannerById(10L)
|
||||||
|
Mockito.verify(bannerService).updateBannerResponse(
|
||||||
|
bannerId = eqLong(10L),
|
||||||
|
imagePath = anyStringValue(),
|
||||||
|
seriesId = eqLong(20L),
|
||||||
|
imageHost = eqString("https://cdn.test")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -77,15 +130,45 @@ class AdminContentSeriesBannerControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
fun shouldAppendBannerLanguageToSeriesTitleInBannerList() {
|
fun shouldAppendBannerLanguageToSeriesTitleInBannerList() {
|
||||||
val pageable = PageRequest.of(0, 20)
|
val pageable = PageRequest.of(0, 20)
|
||||||
val japaneseBanner = createBanner(id = 12L, lang = Lang.JA, imagePath = "banner/jp.png")
|
val serviceResponse = SeriesBannerListPageResponse(
|
||||||
|
totalCount = 1,
|
||||||
|
content = listOf(
|
||||||
|
SeriesBannerResponse(
|
||||||
|
id = 12L,
|
||||||
|
imagePath = "https://cdn.test/banner/jp.png",
|
||||||
|
seriesId = 12L,
|
||||||
|
seriesTitle = "series-12 (일본어)"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
Mockito.`when`(bannerService.getActiveBanners(pageable))
|
Mockito.`when`(bannerService.getActiveBanners(pageable, "https://cdn.test"))
|
||||||
.thenReturn(PageImpl(listOf(japaneseBanner), pageable, 1))
|
.thenReturn(serviceResponse)
|
||||||
|
|
||||||
val response = controller.getBannerList(page = 0, size = 20)
|
val response = controller.getBannerList(page = 0, size = 20)
|
||||||
|
|
||||||
assertTrue(response.success)
|
assertTrue(response.success)
|
||||||
assertEquals("series-12 (일본어)", response.data?.content?.first()?.seriesTitle)
|
assertEquals("series-12 (일본어)", response.data?.content?.first()?.seriesTitle)
|
||||||
|
Mockito.verify(bannerService).getActiveBanners(pageable, "https://cdn.test")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldDelegateBannerDetailResponseToService() {
|
||||||
|
val serviceResponse = SeriesBannerResponse(
|
||||||
|
id = 12L,
|
||||||
|
imagePath = "https://cdn.test/banner/jp.png",
|
||||||
|
seriesId = 12L,
|
||||||
|
seriesTitle = "series-12"
|
||||||
|
)
|
||||||
|
|
||||||
|
Mockito.`when`(bannerService.getBannerDetailResponse(12L, "https://cdn.test"))
|
||||||
|
.thenReturn(serviceResponse)
|
||||||
|
|
||||||
|
val response = controller.getBannerDetail(bannerId = 12L)
|
||||||
|
|
||||||
|
assertTrue(response.success)
|
||||||
|
assertEquals("series-12", response.data?.seriesTitle)
|
||||||
|
Mockito.verify(bannerService).getBannerDetailResponse(12L, "https://cdn.test")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createBanner(id: Long, lang: Lang, imagePath: String): SeriesBanner {
|
private fun createBanner(id: Long, lang: Lang, imagePath: String): SeriesBanner {
|
||||||
@@ -105,4 +188,12 @@ class AdminContentSeriesBannerControllerTest {
|
|||||||
it.id = id
|
it.id = id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun anyStringValue(): String = Mockito.anyString() ?: ""
|
||||||
|
|
||||||
|
private fun eqLong(value: Long): Long = Mockito.eq(value)
|
||||||
|
|
||||||
|
private fun eqString(value: String): String = Mockito.eq(value) ?: value
|
||||||
|
|
||||||
|
private fun nullLongValue(): Long? = Mockito.isNull()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
package kr.co.vividnext.sodalive.content.series.main
|
package kr.co.vividnext.sodalive.content.series.main
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.series.banner.dto.SeriesBannerResponse
|
||||||
import kr.co.vividnext.sodalive.content.ContentType
|
import kr.co.vividnext.sodalive.content.ContentType
|
||||||
import kr.co.vividnext.sodalive.content.series.ContentSeriesService
|
import kr.co.vividnext.sodalive.content.series.ContentSeriesService
|
||||||
import kr.co.vividnext.sodalive.content.series.GetSeriesListResponse
|
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.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.Lang
|
||||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
@@ -15,7 +14,6 @@ import org.junit.jupiter.api.Assertions.assertEquals
|
|||||||
import org.junit.jupiter.api.Assertions.assertTrue
|
import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.mockito.Mockito
|
import org.mockito.Mockito
|
||||||
import org.springframework.data.domain.PageImpl
|
|
||||||
import org.springframework.data.domain.PageRequest
|
import org.springframework.data.domain.PageRequest
|
||||||
|
|
||||||
class SeriesMainControllerTest {
|
class SeriesMainControllerTest {
|
||||||
@@ -41,18 +39,16 @@ class SeriesMainControllerTest {
|
|||||||
isAdult = true
|
isAdult = true
|
||||||
)
|
)
|
||||||
val pageable = PageRequest.of(0, 10)
|
val pageable = PageRequest.of(0, 10)
|
||||||
val japaneseBanner = SeriesBanner(
|
val japaneseBanner = SeriesBannerResponse(
|
||||||
imagePath = "banner/jp.png",
|
id = 100L,
|
||||||
series = createSeries(id = 10L),
|
imagePath = "https://cdn.test/banner/jp.png",
|
||||||
sortOrder = 1,
|
seriesId = 10L,
|
||||||
lang = Lang.JA
|
seriesTitle = "series-10"
|
||||||
).also {
|
)
|
||||||
it.id = 100L
|
|
||||||
}
|
|
||||||
|
|
||||||
Mockito.`when`(memberContentPreferenceService.resolveForQuery(member)).thenReturn(preference)
|
Mockito.`when`(memberContentPreferenceService.resolveForQuery(member)).thenReturn(preference)
|
||||||
Mockito.`when`(bannerService.getDisplayBanners(pageable, Lang.JA))
|
Mockito.`when`(bannerService.getDisplayBannerResponses(pageable, Lang.JA, "https://cdn.test"))
|
||||||
.thenReturn(PageImpl(listOf(japaneseBanner), pageable, 1))
|
.thenReturn(listOf(japaneseBanner))
|
||||||
Mockito.`when`(
|
Mockito.`when`(
|
||||||
contentSeriesService.getSeriesList(
|
contentSeriesService.getSeriesList(
|
||||||
null,
|
null,
|
||||||
@@ -79,8 +75,8 @@ class SeriesMainControllerTest {
|
|||||||
assertTrue(response.success)
|
assertTrue(response.success)
|
||||||
assertEquals(1, response.data?.banners?.size)
|
assertEquals(1, response.data?.banners?.size)
|
||||||
assertEquals("series-10", response.data?.banners?.first()?.seriesTitle)
|
assertEquals("series-10", response.data?.banners?.first()?.seriesTitle)
|
||||||
Mockito.verify(bannerService).getDisplayBanners(pageable, Lang.JA)
|
Mockito.verify(bannerService).getDisplayBannerResponses(pageable, Lang.JA, "https://cdn.test")
|
||||||
Mockito.verify(bannerService, Mockito.never()).getActiveBanners(pageable)
|
Mockito.verify(bannerService, Mockito.never()).getActiveBanners(pageable, "https://cdn.test")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createMember(id: Long): Member {
|
private fun createMember(id: Long): Member {
|
||||||
@@ -92,14 +88,4 @@ class SeriesMainControllerTest {
|
|||||||
it.id = id
|
it.id = id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createSeries(id: Long): Series {
|
|
||||||
return Series(
|
|
||||||
title = "series-$id",
|
|
||||||
introduction = "introduction-$id",
|
|
||||||
languageCode = "ja"
|
|
||||||
).also {
|
|
||||||
it.id = id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user