test #415
@@ -110,6 +110,7 @@ class AdminAudioContentQueryRepositoryImpl(
|
||||
audioContentTheme.theme,
|
||||
audioContentTheme.id,
|
||||
audioContent.price,
|
||||
audioContent.settlementRatio,
|
||||
audioContent.limited,
|
||||
audioContent.remaining,
|
||||
audioContent.isAdult,
|
||||
|
||||
@@ -93,7 +93,8 @@ class AdminContentService(
|
||||
|
||||
@Transactional
|
||||
fun updateAudioContent(coverImage: MultipartFile?, requestString: String) {
|
||||
val request = objectMapper.readValue(requestString, UpdateAdminContentRequest::class.java)
|
||||
val requestNode = objectMapper.readTree(requestString)
|
||||
val request = objectMapper.treeToValue(requestNode, UpdateAdminContentRequest::class.java)
|
||||
val audioContent = repository.findByIdOrNull(id = request.id)
|
||||
?: throw SodaException(messageKey = "admin.content.not_found")
|
||||
|
||||
@@ -145,6 +146,18 @@ class AdminContentService(
|
||||
val theme = themeRepository.findByIdAndActive(id = request.themeId)
|
||||
audioContent.theme = theme
|
||||
}
|
||||
|
||||
if (request.isSettlementRatioDeleted == true) {
|
||||
if (requestNode.has("settlementRatio")) {
|
||||
throw SodaException(messageKey = "common.error.invalid_request")
|
||||
}
|
||||
audioContent.settlementRatio = null
|
||||
} else if (request.settlementRatio != null) {
|
||||
if (request.settlementRatio !in 0..100) {
|
||||
throw SodaException(messageKey = "common.error.invalid_request")
|
||||
}
|
||||
audioContent.settlementRatio = request.settlementRatio
|
||||
}
|
||||
}
|
||||
|
||||
fun getContentMainTabList(): List<GetContentMainTabItem> {
|
||||
|
||||
@@ -18,6 +18,7 @@ data class GetAdminContentListItem @QueryProjection constructor(
|
||||
val theme: String,
|
||||
val themeId: Long,
|
||||
val price: Int,
|
||||
val settlementRatio: Int?,
|
||||
val totalContentCount: Int?,
|
||||
val remainingContentCount: Int?,
|
||||
val isAdult: Boolean,
|
||||
|
||||
@@ -7,6 +7,8 @@ data class UpdateAdminContentRequest(
|
||||
val detail: String?,
|
||||
val curationId: Long?,
|
||||
val themeId: Long?,
|
||||
val settlementRatio: Int?,
|
||||
val isSettlementRatioDeleted: Boolean?,
|
||||
val isAdult: Boolean?,
|
||||
val isActive: Boolean?,
|
||||
val isCommentAvailable: Boolean?
|
||||
|
||||
@@ -35,6 +35,7 @@ data class AudioContent(
|
||||
var languageCode: String?,
|
||||
var playCount: Long = 0,
|
||||
var price: Int = 0,
|
||||
var settlementRatio: Int? = null,
|
||||
var releaseDate: LocalDateTime? = null,
|
||||
val limited: Int? = null,
|
||||
var remaining: Int? = null,
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
package kr.co.vividnext.sodalive.admin.content
|
||||
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import kr.co.vividnext.sodalive.admin.content.curation.AdminContentCurationRepository
|
||||
import kr.co.vividnext.sodalive.admin.content.tab.AdminContentMainTabRepository
|
||||
import kr.co.vividnext.sodalive.admin.content.theme.AdminContentThemeRepository
|
||||
import kr.co.vividnext.sodalive.aws.cloudfront.AudioContentCloudFront
|
||||
import kr.co.vividnext.sodalive.aws.s3.S3Uploader
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.content.AudioContent
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNull
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.Mockito
|
||||
import java.util.Optional
|
||||
|
||||
class AdminContentServiceTest {
|
||||
private lateinit var repository: AdminContentRepository
|
||||
private lateinit var themeRepository: AdminContentThemeRepository
|
||||
private lateinit var audioContentCloudFront: AudioContentCloudFront
|
||||
private lateinit var curationRepository: AdminContentCurationRepository
|
||||
private lateinit var contentMainTabRepository: AdminContentMainTabRepository
|
||||
private lateinit var s3Uploader: S3Uploader
|
||||
private lateinit var service: AdminContentService
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
repository = Mockito.mock(AdminContentRepository::class.java)
|
||||
themeRepository = Mockito.mock(AdminContentThemeRepository::class.java)
|
||||
audioContentCloudFront = Mockito.mock(AudioContentCloudFront::class.java)
|
||||
curationRepository = Mockito.mock(AdminContentCurationRepository::class.java)
|
||||
contentMainTabRepository = Mockito.mock(AdminContentMainTabRepository::class.java)
|
||||
s3Uploader = Mockito.mock(S3Uploader::class.java)
|
||||
|
||||
service = AdminContentService(
|
||||
repository = repository,
|
||||
themeRepository = themeRepository,
|
||||
audioContentCloudFront = audioContentCloudFront,
|
||||
curationRepository = curationRepository,
|
||||
contentMainTabRepository = contentMainTabRepository,
|
||||
objectMapper = jacksonObjectMapper(),
|
||||
s3Uploader = s3Uploader,
|
||||
bucket = "test-bucket"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("관리자 콘텐츠 수정은 유효한 개별 정산 요율을 저장한다")
|
||||
fun shouldUpdateSettlementRatioWhenValidValueIsProvided() {
|
||||
val audioContent = createAudioContent(settlementRatio = 70)
|
||||
Mockito.`when`(repository.findById(1L)).thenReturn(Optional.of(audioContent))
|
||||
|
||||
service.updateAudioContent(
|
||||
coverImage = null,
|
||||
requestString = """
|
||||
{"id":1,"isDefaultCoverImage":false,"settlementRatio":80}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
assertEquals(80, audioContent.settlementRatio)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("관리자 콘텐츠 수정은 삭제 플래그로 개별 정산 요율을 삭제한다")
|
||||
fun shouldDeleteSettlementRatioWhenDeleteFlagIsTrue() {
|
||||
val audioContent = createAudioContent(settlementRatio = 70)
|
||||
Mockito.`when`(repository.findById(1L)).thenReturn(Optional.of(audioContent))
|
||||
|
||||
service.updateAudioContent(
|
||||
coverImage = null,
|
||||
requestString = """
|
||||
{"id":1,"isDefaultCoverImage":false,"isSettlementRatioDeleted":true}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
assertNull(audioContent.settlementRatio)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("관리자 콘텐츠 수정은 삭제 플래그와 정산 요율을 함께 보내면 예외를 던진다")
|
||||
fun shouldThrowWhenDeleteFlagAndSettlementRatioAreProvidedTogether() {
|
||||
val audioContent = createAudioContent(settlementRatio = 70)
|
||||
Mockito.`when`(repository.findById(1L)).thenReturn(Optional.of(audioContent))
|
||||
|
||||
val exception = assertThrows(SodaException::class.java) {
|
||||
service.updateAudioContent(
|
||||
coverImage = null,
|
||||
requestString = """
|
||||
{"id":1,"isDefaultCoverImage":false,"settlementRatio":80,"isSettlementRatioDeleted":true}
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
assertEquals("common.error.invalid_request", exception.messageKey)
|
||||
assertEquals(70, audioContent.settlementRatio)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("관리자 콘텐츠 수정은 삭제 플래그와 null 정산 요율 키를 함께 보내도 예외를 던진다")
|
||||
fun shouldThrowWhenDeleteFlagAndNullSettlementRatioKeyAreProvidedTogether() {
|
||||
val audioContent = createAudioContent(settlementRatio = 70)
|
||||
Mockito.`when`(repository.findById(1L)).thenReturn(Optional.of(audioContent))
|
||||
|
||||
val exception = assertThrows(SodaException::class.java) {
|
||||
service.updateAudioContent(
|
||||
coverImage = null,
|
||||
requestString = """
|
||||
{"id":1,"isDefaultCoverImage":false,"settlementRatio":null,"isSettlementRatioDeleted":true}
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
assertEquals("common.error.invalid_request", exception.messageKey)
|
||||
assertEquals(70, audioContent.settlementRatio)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("관리자 콘텐츠 수정은 범위를 벗어난 정산 요율이면 예외를 던진다")
|
||||
fun shouldThrowWhenSettlementRatioIsOutOfRange() {
|
||||
val audioContent = createAudioContent(settlementRatio = 70)
|
||||
Mockito.`when`(repository.findById(1L)).thenReturn(Optional.of(audioContent))
|
||||
|
||||
val exception = assertThrows(SodaException::class.java) {
|
||||
service.updateAudioContent(
|
||||
coverImage = null,
|
||||
requestString = """
|
||||
{"id":1,"isDefaultCoverImage":false,"settlementRatio":101}
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
assertEquals("common.error.invalid_request", exception.messageKey)
|
||||
assertEquals(70, audioContent.settlementRatio)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("관리자 콘텐츠 수정은 삭제 플래그와 정산 요율이 없으면 기존 값을 유지한다")
|
||||
fun shouldKeepSettlementRatioWhenNoSettlementRatioFieldsAreProvided() {
|
||||
val audioContent = createAudioContent(settlementRatio = 70)
|
||||
Mockito.`when`(repository.findById(1L)).thenReturn(Optional.of(audioContent))
|
||||
|
||||
service.updateAudioContent(
|
||||
coverImage = null,
|
||||
requestString = """
|
||||
{"id":1,"isDefaultCoverImage":false}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
assertEquals(70, audioContent.settlementRatio)
|
||||
}
|
||||
|
||||
private fun createAudioContent(settlementRatio: Int?): AudioContent {
|
||||
return AudioContent(
|
||||
title = "title",
|
||||
detail = "detail",
|
||||
languageCode = "ko",
|
||||
price = 100,
|
||||
settlementRatio = settlementRatio
|
||||
).apply {
|
||||
id = 1L
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user