test: postServiceImplのテストを追加

This commit is contained in:
usbharu 2023-11-07 12:52:27 +09:00
parent 9e7d833a3d
commit c6cd6e82cf
2 changed files with 150 additions and 6 deletions

View File

@ -0,0 +1,144 @@
package dev.usbharu.hideout.core.service.post
import dev.usbharu.hideout.activitypub.service.activity.create.ApSendCreateService
import dev.usbharu.hideout.application.config.CharacterLimit
import dev.usbharu.hideout.core.domain.model.post.Post
import dev.usbharu.hideout.core.domain.model.post.PostRepository
import dev.usbharu.hideout.core.domain.model.user.UserRepository
import dev.usbharu.hideout.core.query.PostQueryService
import dev.usbharu.hideout.core.service.timeline.TimelineService
import kotlinx.coroutines.test.runTest
import org.assertj.core.api.Assertions.assertThat
import org.jetbrains.exposed.exceptions.ExposedSQLException
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.mockStatic
import org.mockito.Spy
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.*
import org.springframework.dao.DuplicateKeyException
import utils.PostBuilder
import utils.UserBuilder
import java.time.Instant
@ExtendWith(MockitoExtension::class)
class PostServiceImplTest {
@Mock
private lateinit var postRepository: PostRepository
@Mock
private lateinit var userRepository: UserRepository
@Mock
private lateinit var timelineService: TimelineService
@Mock
private lateinit var postQueryService: PostQueryService
@Spy
private var postBuilder: Post.PostBuilder = Post.PostBuilder(CharacterLimit())
@Mock
private lateinit var apSendCreateService: ApSendCreateService
@InjectMocks
private lateinit var postServiceImpl: PostServiceImpl
@Test
fun `createLocal 正常にpostを作成できる`() = runTest {
val now = Instant.now()
val post = PostBuilder.of(createdAt = now.toEpochMilli())
whenever(postRepository.save(eq(post))).doReturn(true)
whenever(postRepository.generateId()).doReturn(post.id)
whenever(userRepository.findById(eq(post.userId))).doReturn(UserBuilder.localUserOf(id = post.userId))
whenever(timelineService.publishTimeline(eq(post), eq(true))).doReturn(Unit)
mockStatic(Instant::class.java, Mockito.CALLS_REAL_METHODS).use {
it.`when`<Instant>(Instant::now).doReturn(now)
val createLocal = postServiceImpl.createLocal(
PostCreateDto(
post.text,
post.overview,
post.visibility,
post.repostId,
post.replyId,
post.userId,
post.mediaIds
)
)
assertThat(createLocal).isEqualTo(post)
}
verify(postRepository, times(1)).save(eq(post))
verify(timelineService, times(1)).publishTimeline(eq(post), eq(true))
verify(apSendCreateService, times(1)).createNote(eq(post))
}
@Test
fun `createRemote 正常にリモートのpostを作成できる`() = runTest {
val post = PostBuilder.of()
whenever(postRepository.save(eq(post))).doReturn(true)
whenever(timelineService.publishTimeline(eq(post), eq(false))).doReturn(Unit)
val createLocal = postServiceImpl.createRemote(post)
assertThat(createLocal).isEqualTo(post)
verify(postRepository, times(1)).save(eq(post))
verify(timelineService, times(1)).publishTimeline(eq(post), eq(false))
}
@Test
fun `createRemote 既に作成されていた場合はそのまま帰す`() = runTest {
val post = PostBuilder.of()
whenever(postRepository.save(eq(post))).doReturn(false)
val createLocal = postServiceImpl.createRemote(post)
assertThat(createLocal).isEqualTo(post)
verify(postRepository, times(1)).save(eq(post))
verify(timelineService, times(0)).publishTimeline(any(), any())
}
@Test
fun `createRemote 既に作成されていることを検知できず例外が発生した場合はDBから取得して返す`() = runTest {
val post = PostBuilder.of()
whenever(postRepository.save(eq(post))).doAnswer { throw ExposedSQLException(null, emptyList(), mock()) }
whenever(postQueryService.findByApId(eq(post.apId))).doReturn(post)
val createLocal = postServiceImpl.createRemote(post)
assertThat(createLocal).isEqualTo(post)
verify(postRepository, times(1)).save(eq(post))
verify(timelineService, times(0)).publishTimeline(any(), any())
}
@Test
fun `createRemote 既に作成されていることを検知出来ずタイムラインにpush出来なかった場合何もしない`() = runTest {
val post = PostBuilder.of()
whenever(postRepository.save(eq(post))).doReturn(true)
whenever(timelineService.publishTimeline(eq(post), eq(false))).doThrow(DuplicateKeyException::class)
val createLocal = postServiceImpl.createRemote(post)
assertThat(createLocal).isEqualTo(post)
verify(postRepository, times(1)).save(eq(post))
verify(timelineService, times(1)).publishTimeline(eq(post), eq(false))
}
}

View File

@ -20,15 +20,15 @@ object UserBuilder {
screenName: String = name,
description: String = "This user is test user.",
password: String = "password-$id",
inbox: String = "https://$domain/$id/inbox",
outbox: String = "https://$domain/$id/outbox",
url: String = "https://$domain/$id/",
inbox: String = "https://$domain/users/$id/inbox",
outbox: String = "https://$domain/users/$id/outbox",
url: String = "https://$domain/users/$id",
publicKey: String = "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----",
privateKey: String = "-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----",
createdAt: Instant = Instant.now(),
keyId: String = "https://$domain/$id#pubkey",
followers: String = "https://$domain/$id/followers",
following: String = "https://$domain/$id/following"
keyId: String = "https://$domain/users/$id#pubkey",
followers: String = "https://$domain/users/$id/followers",
following: String = "https://$domain/users/$id/following"
): User {
return userBuilder.of(
id = id,