test #449
+166
-1
@@ -6,10 +6,12 @@ import com.fasterxml.jackson.databind.ObjectMapper
|
|||||||
import kr.co.vividnext.sodalive.chat.character.service.ChatCharacterService
|
import kr.co.vividnext.sodalive.chat.character.service.ChatCharacterService
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunity
|
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunity
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunityRepository
|
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunityRepository
|
||||||
|
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunityService
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
import kr.co.vividnext.sodalive.member.MemberAdapter
|
import kr.co.vividnext.sodalive.member.MemberAdapter
|
||||||
import kr.co.vividnext.sodalive.member.MemberRole
|
import kr.co.vividnext.sodalive.member.MemberRole
|
||||||
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
|
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
|
||||||
|
import kr.co.vividnext.sodalive.v2.creator.channel.community.translation.application.CreatorCommunityTranslationService
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.Assertions.assertFalse
|
import org.junit.jupiter.api.Assertions.assertFalse
|
||||||
import org.junit.jupiter.api.Assertions.assertNotNull
|
import org.junit.jupiter.api.Assertions.assertNotNull
|
||||||
@@ -54,7 +56,8 @@ class AiCharacterAdminCommunityPostConcurrencyTest @Autowired constructor(
|
|||||||
private val chatCharacterService: ChatCharacterService,
|
private val chatCharacterService: ChatCharacterService,
|
||||||
private val objectMapper: ObjectMapper,
|
private val objectMapper: ObjectMapper,
|
||||||
private val entityManager: EntityManager,
|
private val entityManager: EntityManager,
|
||||||
private val transactionManager: PlatformTransactionManager
|
private val transactionManager: PlatformTransactionManager,
|
||||||
|
private val creatorCommunityService: CreatorCommunityService
|
||||||
) {
|
) {
|
||||||
@MockBean
|
@MockBean
|
||||||
private lateinit var amazonS3Client: AmazonS3Client
|
private lateinit var amazonS3Client: AmazonS3Client
|
||||||
@@ -62,9 +65,15 @@ class AiCharacterAdminCommunityPostConcurrencyTest @Autowired constructor(
|
|||||||
@MockBean
|
@MockBean
|
||||||
private lateinit var applicationEventPublisher: ApplicationEventPublisher
|
private lateinit var applicationEventPublisher: ApplicationEventPublisher
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private lateinit var creatorCommunityTranslationService: CreatorCommunityTranslationService
|
||||||
|
|
||||||
@SpyBean
|
@SpyBean
|
||||||
private lateinit var creatorCommunityRepository: CreatorCommunityRepository
|
private lateinit var creatorCommunityRepository: CreatorCommunityRepository
|
||||||
|
|
||||||
|
@SpyBean
|
||||||
|
private lateinit var aiCharacterAdminCommunityPostRepository: AiCharacterAdminCommunityPostRepository
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("순차 고정 요청에서 세 번째는 허용되고 네 번째는 최대 고정 수로 거부된다")
|
@DisplayName("순차 고정 요청에서 세 번째는 허용되고 네 번째는 최대 고정 수로 거부된다")
|
||||||
fun shouldAllowThirdFixedPostAndRejectFourthWhenRequestsAreSerialized() {
|
fun shouldAllowThirdFixedPostAndRejectFourthWhenRequestsAreSerialized() {
|
||||||
@@ -167,6 +176,133 @@ class AiCharacterAdminCommunityPostConcurrencyTest @Autowired constructor(
|
|||||||
assertEquals(3L, transactionTemplate.execute { fixedPostCount(fixture.ownerId) })
|
assertEquals(3L, transactionTemplate.execute { fixedPostCount(fixture.ownerId) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||||
|
@DisplayName("병렬 본문 수정은 현재 행 잠금으로 개정을 순서대로 증가시킨다")
|
||||||
|
fun shouldSerializeContentRevisionsWhenUpdatesRace() {
|
||||||
|
val transactionTemplate = TransactionTemplate(transactionManager)
|
||||||
|
val fixture = transactionTemplate.execute {
|
||||||
|
val character = createCharacter("community-content-race")
|
||||||
|
val post = savePost(character.creatorMember!!, "before").apply {
|
||||||
|
languageCode = "ko"
|
||||||
|
contentRevision = 0
|
||||||
|
}
|
||||||
|
entityManager.flush()
|
||||||
|
ContentRaceFixture(character.id!!, post.id!!)
|
||||||
|
} ?: throw IllegalStateException("fixture creation failed")
|
||||||
|
|
||||||
|
val executor = Executors.newFixedThreadPool(2)
|
||||||
|
val updatesReady = CountDownLatch(2)
|
||||||
|
val startUpdates = CountDownLatch(1)
|
||||||
|
try {
|
||||||
|
val first = executor.submit<Int> {
|
||||||
|
updatesReady.countDown()
|
||||||
|
startUpdates.await(5, TimeUnit.SECONDS)
|
||||||
|
mockMvc.perform(updateContentRequest(fixture.characterId, fixture.postId, "first"))
|
||||||
|
.andReturn()
|
||||||
|
.response
|
||||||
|
.status
|
||||||
|
}
|
||||||
|
|
||||||
|
val second = executor.submit<Int> {
|
||||||
|
updatesReady.countDown()
|
||||||
|
startUpdates.await(5, TimeUnit.SECONDS)
|
||||||
|
mockMvc.perform(updateContentRequest(fixture.characterId, fixture.postId, "second"))
|
||||||
|
.andReturn()
|
||||||
|
.response
|
||||||
|
.status
|
||||||
|
}
|
||||||
|
assertTrue(updatesReady.await(5, TimeUnit.SECONDS))
|
||||||
|
startUpdates.countDown()
|
||||||
|
assertEquals(listOf(200, 200), listOf(first.get(5, TimeUnit.SECONDS), second.get(5, TimeUnit.SECONDS)))
|
||||||
|
} finally {
|
||||||
|
startUpdates.countDown()
|
||||||
|
executor.shutdown()
|
||||||
|
assertTrue(executor.awaitTermination(5, TimeUnit.SECONDS))
|
||||||
|
}
|
||||||
|
|
||||||
|
val updated = transactionTemplate.execute {
|
||||||
|
entityManager.clear()
|
||||||
|
entityManager.find(CreatorCommunity::class.java, fixture.postId)
|
||||||
|
}!!
|
||||||
|
assertEquals(2, updated.contentRevision)
|
||||||
|
assertTrue(updated.content == "first" || updated.content == "second")
|
||||||
|
Mockito.verify(creatorCommunityTranslationService, Mockito.times(2)).requestTranslations(fixture.postId, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||||
|
@DisplayName("고정 상태의 stale read는 최신 본문 수정의 개정과 언어를 덮어쓰지 않는다")
|
||||||
|
fun shouldApplyFixedAndContentUpdateAfterConcurrentContentCommit() {
|
||||||
|
val transactionTemplate = TransactionTemplate(transactionManager)
|
||||||
|
val fixture = transactionTemplate.execute {
|
||||||
|
val character = createCharacter("community-fixed-content-race")
|
||||||
|
val post = savePost(character.creatorMember!!, "before").apply {
|
||||||
|
languageCode = "ko"
|
||||||
|
contentRevision = 0
|
||||||
|
}
|
||||||
|
entityManager.flush()
|
||||||
|
ContentRaceFixture(character.id!!, post.id!!)
|
||||||
|
} ?: throw IllegalStateException("fixture creation failed")
|
||||||
|
val staleAdminRead = CountDownLatch(1)
|
||||||
|
val releaseFixedUpdate = CountDownLatch(1)
|
||||||
|
val contentUpdatePreLock = CountDownLatch(1)
|
||||||
|
val fixedReadPaused = AtomicBoolean(false)
|
||||||
|
Mockito.doAnswer { invocation ->
|
||||||
|
val post = invocation.callRealMethod() as CreatorCommunity?
|
||||||
|
if (post?.id == fixture.postId && fixedReadPaused.compareAndSet(false, true)) {
|
||||||
|
staleAdminRead.countDown()
|
||||||
|
releaseFixedUpdate.await(5, TimeUnit.SECONDS)
|
||||||
|
}
|
||||||
|
post
|
||||||
|
}.`when`(aiCharacterAdminCommunityPostRepository)
|
||||||
|
.findActiveByIdAndCreatorMemberId(Mockito.anyLong(), Mockito.anyLong())
|
||||||
|
|
||||||
|
val executor = Executors.newFixedThreadPool(2)
|
||||||
|
try {
|
||||||
|
val fixedAndContent = executor.submit<Int> {
|
||||||
|
mockMvc.perform(fixedAndContentRequest(fixture.characterId, fixture.postId, "after fixed"))
|
||||||
|
.andReturn()
|
||||||
|
.response
|
||||||
|
.status
|
||||||
|
}
|
||||||
|
assertTrue(staleAdminRead.await(5, TimeUnit.SECONDS))
|
||||||
|
|
||||||
|
val concurrentContent = executor.submit<Int> {
|
||||||
|
contentUpdatePreLock.countDown()
|
||||||
|
creatorCommunityService.modifyCommunityPost(
|
||||||
|
postImage = null,
|
||||||
|
requestString = objectMapper.writeValueAsString(
|
||||||
|
mapOf("creatorCommunityId" to fixture.postId, "content" to "after concurrent")
|
||||||
|
),
|
||||||
|
member = transactionTemplate.execute {
|
||||||
|
entityManager.find(CreatorCommunity::class.java, fixture.postId).member!!
|
||||||
|
}!!
|
||||||
|
)
|
||||||
|
200
|
||||||
|
}
|
||||||
|
assertTrue(contentUpdatePreLock.await(5, TimeUnit.SECONDS))
|
||||||
|
assertEquals(200, concurrentContent.get(5, TimeUnit.SECONDS))
|
||||||
|
|
||||||
|
releaseFixedUpdate.countDown()
|
||||||
|
assertEquals(200, fixedAndContent.get(5, TimeUnit.SECONDS))
|
||||||
|
} finally {
|
||||||
|
releaseFixedUpdate.countDown()
|
||||||
|
executor.shutdown()
|
||||||
|
assertTrue(executor.awaitTermination(5, TimeUnit.SECONDS))
|
||||||
|
}
|
||||||
|
|
||||||
|
val updated = transactionTemplate.execute {
|
||||||
|
entityManager.clear()
|
||||||
|
entityManager.find(CreatorCommunity::class.java, fixture.postId)
|
||||||
|
}!!
|
||||||
|
assertEquals("after fixed", updated.content)
|
||||||
|
assertEquals(2, updated.contentRevision)
|
||||||
|
assertEquals(null, updated.languageCode)
|
||||||
|
assertTrue(updated.isFixed)
|
||||||
|
assertNotNull(updated.fixedAt)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("invalid target와 cross-owner 고정 요청은 DB, S3, event 변경 없이 거부된다")
|
@DisplayName("invalid target와 cross-owner 고정 요청은 DB, S3, event 변경 없이 거부된다")
|
||||||
fun shouldRejectInvalidTargetAndCrossOwnerFixedRequestsWithoutSideEffects() {
|
fun shouldRejectInvalidTargetAndCrossOwnerFixedRequestsWithoutSideEffects() {
|
||||||
@@ -213,6 +349,30 @@ class AiCharacterAdminCommunityPostConcurrencyTest @Autowired constructor(
|
|||||||
postImage?.let(::file)
|
postImage?.let(::file)
|
||||||
}.with(adminAuthentication())
|
}.with(adminAuthentication())
|
||||||
|
|
||||||
|
private fun updateContentRequest(characterId: Long, postId: Long, content: String) =
|
||||||
|
multipart(HttpMethod.PUT, "/api/v2/admin/ai-characters/$characterId/community-posts/$postId")
|
||||||
|
.file(
|
||||||
|
MockMultipartFile(
|
||||||
|
"request",
|
||||||
|
"request.json",
|
||||||
|
MediaType.APPLICATION_JSON_VALUE,
|
||||||
|
objectMapper.writeValueAsBytes(mapOf("content" to content))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.with(adminAuthentication())
|
||||||
|
|
||||||
|
private fun fixedAndContentRequest(characterId: Long, postId: Long, content: String) =
|
||||||
|
multipart(HttpMethod.PUT, "/api/v2/admin/ai-characters/$characterId/community-posts/$postId")
|
||||||
|
.file(
|
||||||
|
MockMultipartFile(
|
||||||
|
"request",
|
||||||
|
"request.json",
|
||||||
|
MediaType.APPLICATION_JSON_VALUE,
|
||||||
|
objectMapper.writeValueAsBytes(mapOf("isFixed" to true, "content" to content))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.with(adminAuthentication())
|
||||||
|
|
||||||
private fun pngFile() = MockMultipartFile(
|
private fun pngFile() = MockMultipartFile(
|
||||||
"postImage",
|
"postImage",
|
||||||
"post.png",
|
"post.png",
|
||||||
@@ -283,4 +443,9 @@ class AiCharacterAdminCommunityPostConcurrencyTest @Autowired constructor(
|
|||||||
val firstPostId: Long,
|
val firstPostId: Long,
|
||||||
val secondPostId: Long
|
val secondPostId: Long
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private data class ContentRaceFixture(
|
||||||
|
val characterId: Long,
|
||||||
|
val postId: Long
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+20
@@ -8,6 +8,7 @@ import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommuni
|
|||||||
import kr.co.vividnext.sodalive.member.MemberAdapter
|
import kr.co.vividnext.sodalive.member.MemberAdapter
|
||||||
import kr.co.vividnext.sodalive.member.MemberRole
|
import kr.co.vividnext.sodalive.member.MemberRole
|
||||||
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
|
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
|
||||||
|
import kr.co.vividnext.sodalive.v2.creator.channel.community.translation.application.CreatorCommunityTranslationService
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.Assertions.assertNotNull
|
import org.junit.jupiter.api.Assertions.assertNotNull
|
||||||
import org.junit.jupiter.api.Assertions.assertTrue
|
import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
@@ -34,6 +35,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multi
|
|||||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.header
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.header
|
||||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
|
||||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
|
||||||
|
import org.springframework.transaction.annotation.Propagation
|
||||||
import org.springframework.transaction.annotation.Transactional
|
import org.springframework.transaction.annotation.Transactional
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import javax.persistence.EntityManager
|
import javax.persistence.EntityManager
|
||||||
@@ -51,6 +53,9 @@ class AiCharacterAdminCommunityPostCreateTest @Autowired constructor(
|
|||||||
@MockBean
|
@MockBean
|
||||||
private lateinit var amazonS3Client: AmazonS3Client
|
private lateinit var amazonS3Client: AmazonS3Client
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private lateinit var creatorCommunityTranslationService: CreatorCommunityTranslationService
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("정상 무료 게시글 생성은 target 소유자를 작성자로 사용하고 data null을 반환한다")
|
@DisplayName("정상 무료 게시글 생성은 target 소유자를 작성자로 사용하고 data null을 반환한다")
|
||||||
fun shouldCreateFreePostForTargetOwnerAndReturnNullData() {
|
fun shouldCreateFreePostForTargetOwnerAndReturnNullData() {
|
||||||
@@ -73,6 +78,21 @@ class AiCharacterAdminCommunityPostCreateTest @Autowired constructor(
|
|||||||
assertTrue(post.member!!.id != otherCharacter.creatorMember!!.id)
|
assertTrue(post.member!!.id != otherCharacter.creatorMember!!.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||||
|
@DisplayName("관리자 생성은 게시글 커밋 후 공용 번역 요청을 한 번 보낸다")
|
||||||
|
fun shouldRequestTranslationsAfterCommittedAdminCreation() {
|
||||||
|
val character = createCharacter("community-create-translation")
|
||||||
|
val content = "translation request after committed admin creation"
|
||||||
|
|
||||||
|
mockMvc.perform(createRequest(character.id!!, content = content))
|
||||||
|
.andExpect(status().isOk)
|
||||||
|
|
||||||
|
val post = findPost(content)
|
||||||
|
assertNotNull(post)
|
||||||
|
Mockito.verify(creatorCommunityTranslationService).requestTranslations(post!!.id!!, null)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("생성 price 생략은 기본값 0으로 게시글을 생성한다")
|
@DisplayName("생성 price 생략은 기본값 0으로 게시글을 생성한다")
|
||||||
fun shouldCreatePostWithDefaultPriceWhenPriceIsOmitted() {
|
fun shouldCreatePostWithDefaultPriceWhenPriceIsOmitted() {
|
||||||
|
|||||||
+4
@@ -62,6 +62,8 @@ class AiCharacterAdminCommunityPostUpdateTest @Autowired constructor(
|
|||||||
val post = savePost(character.creatorMember!!, "before", isCommentAvailable = true, isAdult = false).apply {
|
val post = savePost(character.creatorMember!!, "before", isCommentAvailable = true, isAdult = false).apply {
|
||||||
isFixed = true
|
isFixed = true
|
||||||
fixedAt = LocalDateTime.now()
|
fixedAt = LocalDateTime.now()
|
||||||
|
languageCode = "ko"
|
||||||
|
contentRevision = 7
|
||||||
}
|
}
|
||||||
entityManager.flush()
|
entityManager.flush()
|
||||||
|
|
||||||
@@ -86,6 +88,8 @@ class AiCharacterAdminCommunityPostUpdateTest @Autowired constructor(
|
|||||||
assertTrue(updated.isAdult)
|
assertTrue(updated.isAdult)
|
||||||
assertTrue(updated.isFixed)
|
assertTrue(updated.isFixed)
|
||||||
assertNotNull(updated.fixedAt)
|
assertNotNull(updated.fixedAt)
|
||||||
|
assertNull(updated.languageCode)
|
||||||
|
assertEquals(8, updated.contentRevision)
|
||||||
Mockito.verifyNoInteractions(amazonS3Client)
|
Mockito.verifyNoInteractions(amazonS3Client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-2
@@ -23,6 +23,7 @@ import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
|||||||
import kr.co.vividnext.sodalive.member.Member
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
import kr.co.vividnext.sodalive.member.MemberRole
|
import kr.co.vividnext.sodalive.member.MemberRole
|
||||||
import kr.co.vividnext.sodalive.member.block.BlockMemberRepository
|
import kr.co.vividnext.sodalive.member.block.BlockMemberRepository
|
||||||
|
import kr.co.vividnext.sodalive.v2.creator.channel.community.translation.application.CreatorCommunityTranslationService
|
||||||
import kr.co.vividnext.sodalive.v2.home.following.application.HomeFollowingNewsPublishService
|
import kr.co.vividnext.sodalive.v2.home.following.application.HomeFollowingNewsPublishService
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.Assertions.assertFalse
|
import org.junit.jupiter.api.Assertions.assertFalse
|
||||||
@@ -37,6 +38,7 @@ import org.springframework.context.ApplicationEventPublisher
|
|||||||
import org.springframework.web.multipart.MultipartFile
|
import org.springframework.web.multipart.MultipartFile
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
import javax.persistence.EntityManager
|
||||||
|
|
||||||
class LegacyCommunityPostCharacterizationTest {
|
class LegacyCommunityPostCharacterizationTest {
|
||||||
private lateinit var repository: CreatorCommunityRepository
|
private lateinit var repository: CreatorCommunityRepository
|
||||||
@@ -65,6 +67,8 @@ class LegacyCommunityPostCharacterizationTest {
|
|||||||
messageSource = SodaMessageSource(),
|
messageSource = SodaMessageSource(),
|
||||||
langContext = LangContext(),
|
langContext = LangContext(),
|
||||||
homeFollowingNewsPublishService = homeFollowingNewsPublishService,
|
homeFollowingNewsPublishService = homeFollowingNewsPublishService,
|
||||||
|
creatorCommunityTranslationService = Mockito.mock(CreatorCommunityTranslationService::class.java),
|
||||||
|
entityManager = Mockito.mock(EntityManager::class.java),
|
||||||
imageBucket = "image-bucket",
|
imageBucket = "image-bucket",
|
||||||
contentBucket = "content-bucket",
|
contentBucket = "content-bucket",
|
||||||
imageHost = "https://cdn.test"
|
imageHost = "https://cdn.test"
|
||||||
@@ -176,7 +180,7 @@ class LegacyCommunityPostCharacterizationTest {
|
|||||||
post.member = creator
|
post.member = creator
|
||||||
post.isFixed = true
|
post.isFixed = true
|
||||||
post.fixedAt = LocalDateTime.of(2026, 7, 28, 10, 0)
|
post.fixedAt = LocalDateTime.of(2026, 7, 28, 10, 0)
|
||||||
Mockito.`when`(repository.findByIdAndMemberId(post.id!!, creator.id!!)).thenReturn(post)
|
Mockito.`when`(repository.findByIdAndMemberIdForUpdate(post.id!!, creator.id!!)).thenReturn(post)
|
||||||
Mockito.`when`(repository.countByMemberIdAndIsFixedIsTrueAndIsActiveIsTrue(creator.id!!)).thenReturn(3L)
|
Mockito.`when`(repository.countByMemberIdAndIsFixedIsTrueAndIsActiveIsTrue(creator.id!!)).thenReturn(3L)
|
||||||
|
|
||||||
service.updateCommunityPostFixed(UpdateCommunityPostFixedRequest(post.id!!, isFixed = true), creator)
|
service.updateCommunityPostFixed(UpdateCommunityPostFixedRequest(post.id!!, isFixed = true), creator)
|
||||||
@@ -193,7 +197,7 @@ class LegacyCommunityPostCharacterizationTest {
|
|||||||
val otherPost = CreatorCommunity("other fixed post", 0, true, false)
|
val otherPost = CreatorCommunity("other fixed post", 0, true, false)
|
||||||
otherPost.id = 1004L
|
otherPost.id = 1004L
|
||||||
otherPost.member = creator
|
otherPost.member = creator
|
||||||
Mockito.`when`(repository.findByIdAndMemberId(otherPost.id!!, creator.id!!)).thenReturn(otherPost)
|
Mockito.`when`(repository.findByIdAndMemberIdForUpdate(otherPost.id!!, creator.id!!)).thenReturn(otherPost)
|
||||||
val exception = assertThrows(SodaException::class.java) {
|
val exception = assertThrows(SodaException::class.java) {
|
||||||
service.updateCommunityPostFixed(UpdateCommunityPostFixedRequest(otherPost.id!!, isFixed = true), creator)
|
service.updateCommunityPostFixed(UpdateCommunityPostFixedRequest(otherPost.id!!, isFixed = true), creator)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user