Merge pull request #379 from usbharu/mock

モックの作成をアノテーションベースに変更する
This commit is contained in:
usbharu 2024-05-18 15:28:08 +09:00 committed by GitHub
commit 525c2acdc3
3 changed files with 143 additions and 255 deletions

View File

@ -23,16 +23,18 @@ import dev.usbharu.hideout.activitypub.domain.model.Image
import dev.usbharu.hideout.activitypub.domain.model.Key
import dev.usbharu.hideout.activitypub.domain.model.Note
import dev.usbharu.hideout.activitypub.domain.model.Person
import dev.usbharu.hideout.activitypub.query.AnnounceQueryService
import dev.usbharu.hideout.activitypub.query.NoteQueryService
import dev.usbharu.hideout.activitypub.service.common.APResourceResolveService
import dev.usbharu.hideout.activitypub.service.objects.emoji.EmojiService
import dev.usbharu.hideout.activitypub.service.objects.note.APNoteServiceImpl.Companion.public
import dev.usbharu.hideout.activitypub.service.objects.user.APUserService
import dev.usbharu.hideout.application.config.CharacterLimit
import dev.usbharu.hideout.application.config.HtmlSanitizeConfig
import dev.usbharu.hideout.application.service.id.TwitterSnowflakeIdGenerateService
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.post.Post
import dev.usbharu.hideout.core.domain.model.post.PostRepository
import dev.usbharu.hideout.core.service.media.MediaService
import dev.usbharu.hideout.core.service.post.DefaultPostContentFormatter
import dev.usbharu.hideout.core.service.post.PostService
import io.ktor.client.*
@ -53,28 +55,58 @@ import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Spy
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.*
import utils.PostBuilder
import utils.UserBuilder
import java.time.Instant
@ExtendWith(MockitoExtension::class)
class APNoteServiceImplTest {
val postBuilder = Post.PostBuilder(
@Mock
private lateinit var postRepository: PostRepository
@Mock
private lateinit var apUserService: APUserService
@Mock
private lateinit var postService: PostService
@Mock
private lateinit var apResourceResolverService: APResourceResolveService
@Spy
private val postBuilder: Post.PostBuilder = Post.PostBuilder(
CharacterLimit(), DefaultPostContentFormatter(HtmlSanitizeConfig().policy()),
Validation.buildDefaultValidatorFactory().validator
)
@Mock
private lateinit var noteQueryService: NoteQueryService
@Mock
private lateinit var mediaService: MediaService
@Mock
private lateinit var emojiService: EmojiService
@Mock
private lateinit var announceQueryService: AnnounceQueryService
@InjectMocks
private lateinit var apNoteServiceImpl: APNoteServiceImpl
@Test
fun `fetchNote(String,String) ートが既に存在する場合はDBから取得したものを返す`() = runTest {
val url = "https://example.com/note"
val post = PostBuilder.of()
val user = UserBuilder.localUserOf(id = post.actorId)
val actorQueryService = mock<ActorRepository> {
onBlocking { findById(eq(post.actorId)) } doReturn user
}
val expected = Note(
id = post.apId,
attributedTo = user.url,
@ -85,20 +117,8 @@ class APNoteServiceImplTest {
cc = listOfNotNull(public, user.followers),
inReplyTo = null
)
val noteQueryService = mock<NoteQueryService> {
onBlocking { findByApid(eq(url)) } doReturn (expected to post)
}
val apNoteServiceImpl = APNoteServiceImpl(
postRepository = mock(),
apUserService = mock(),
postService = mock(),
apResourceResolveService = mock(),
postBuilder = postBuilder,
noteQueryService = noteQueryService,
mock(),
mock(),
mock()
)
whenever(noteQueryService.findByApid(eq(url))).doReturn(expected to post)
val actual = apNoteServiceImpl.fetchNote(url)
@ -123,12 +143,11 @@ class APNoteServiceImplTest {
cc = listOfNotNull(public, user.followers),
inReplyTo = null
)
val apResourceResolveService = mock<APResourceResolveService> {
onBlocking { resolve<Note>(eq(url), any(), isNull<Long>()) } doReturn note
}
val noteQueryService = mock<NoteQueryService> {
onBlocking { findByApid(eq(url)) } doReturn null
}
whenever(apResourceResolverService.resolve<Note>(eq(url), any(), isNull<Long>())).doReturn(note)
whenever(noteQueryService.findByApid(eq(url))).doReturn(null)
val person = Person(
name = user.name,
id = user.url,
@ -153,23 +172,16 @@ class APNoteServiceImplTest {
manuallyApprovesFollowers = false
)
val apUserService = mock<APUserService> {
onBlocking { fetchPersonWithEntity(eq(note.attributedTo), isNull(), anyOrNull()) } doReturn (person to user)
}
val postRepository = mock<PostRepository> {
onBlocking { generateId() } doReturn TwitterSnowflakeIdGenerateService.generateId()
}
val apNoteServiceImpl = APNoteServiceImpl(
postRepository = postRepository,
apUserService = apUserService,
postService = mock(),
apResourceResolveService = apResourceResolveService,
postBuilder = postBuilder,
noteQueryService = noteQueryService,
mock(),
mock { },
mock()
)
whenever(
apUserService.fetchPersonWithEntity(
eq(note.attributedTo),
isNull(),
anyOrNull()
)
).doReturn(person to user)
whenever(postRepository.generateId()).doReturn(TwitterSnowflakeIdGenerateService.generateId())
val actual = apNoteServiceImpl.fetchNote(url)
@ -181,17 +193,16 @@ class APNoteServiceImplTest {
fun `fetchNote(String,String) ートをリモートから取得した際にエラーが返ってきたらFailedToGetActivityPubResourceExceptionがthrowされる`() =
runTest {
val url = "https://example.com/note"
val apResourceResolveService = mock<APResourceResolveService> {
val responseData = HttpResponseData(
HttpStatusCode.BadRequest,
GMTDate(),
Headers.Empty,
HttpProtocolVersion.HTTP_1_1,
NullBody,
Dispatchers.IO
)
onBlocking { resolve<Note>(eq(url), any(), isNull<Long>()) } doThrow ClientRequestException(
val responseData = HttpResponseData(
HttpStatusCode.BadRequest,
GMTDate(),
Headers.Empty,
HttpProtocolVersion.HTTP_1_1,
NullBody,
Dispatchers.IO
)
whenever(apResourceResolverService.resolve<Note>(eq(url), any(), isNull<Long>())).doThrow(
ClientRequestException(
DefaultHttpResponse(
HttpClientCall(
HttpClient(), HttpRequestData(
@ -205,22 +216,10 @@ class APNoteServiceImplTest {
), responseData
), ""
)
}
val noteQueryService = mock<NoteQueryService> {
onBlocking { findByApid(eq(url)) } doReturn null
}
val apNoteServiceImpl = APNoteServiceImpl(
postRepository = mock(),
apUserService = mock(),
postService = mock(),
apResourceResolveService = apResourceResolveService,
postBuilder = postBuilder,
noteQueryService = noteQueryService,
mock(),
mock(),
mock { }
)
whenever(noteQueryService.findByApid(eq(url))).doReturn(null)
assertThrows<FailedToGetActivityPubResourceException> { apNoteServiceImpl.fetchNote(url) }
}
@ -230,9 +229,9 @@ class APNoteServiceImplTest {
val user = UserBuilder.localUserOf()
val generateId = TwitterSnowflakeIdGenerateService.generateId()
val post = PostBuilder.of(id = generateId, userId = user.id)
val postRepository = mock<PostRepository> {
onBlocking { generateId() } doReturn generateId
}
whenever(postRepository.generateId()).doReturn(generateId)
val person = Person(
name = user.name,
id = user.url,
@ -254,24 +253,10 @@ class APNoteServiceImplTest {
following = user.following,
followers = user.followers
)
val apUserService = mock<APUserService> {
onBlocking { fetchPersonWithEntity(eq(user.url), anyOrNull(), anyOrNull()) } doReturn (person to user)
}
val postService = mock<PostService>()
val noteQueryService = mock<NoteQueryService> {
onBlocking { findByApid(eq(post.apId)) } doReturn null
}
val apNoteServiceImpl = APNoteServiceImpl(
postRepository = postRepository,
apUserService = apUserService,
postService = postService,
apResourceResolveService = mock(),
postBuilder = postBuilder,
noteQueryService = noteQueryService,
mock(),
mock(),
mock()
)
whenever(apUserService.fetchPersonWithEntity(eq(user.url), anyOrNull(), anyOrNull())).doReturn(person to user)
whenever(noteQueryService.findByApid(eq(post.apId))).doReturn(null)
val note = Note(
id = post.apId,
@ -312,21 +297,8 @@ class APNoteServiceImplTest {
cc = listOfNotNull(public, user.followers),
inReplyTo = null
)
val noteQueryService = mock<NoteQueryService> {
onBlocking { findByApid(eq(post.apId)) } doReturn (note to post)
}
val apNoteServiceImpl = APNoteServiceImpl(
postRepository = mock(),
apUserService = mock(),
postService = mock(),
apResourceResolveService = mock(),
postBuilder = postBuilder,
noteQueryService = noteQueryService,
mock(),
mock(),
mock()
)
whenever(noteQueryService.findByApid(post.apId)).doReturn(note to post)
val fetchNote = apNoteServiceImpl.fetchNote(note, null)
assertEquals(note, fetchNote)

View File

@ -1,75 +0,0 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
package dev.usbharu.hideout.activitypub.service.objects.note
class ApNoteJobServiceImplTest {
// @Test
// fun `createPostJob 新しい投稿のJob`() = runTest {
// val apRequestService = mock<APRequestService>()
// val user = UserBuilder.localUserOf()
// val userQueryService = mock<UserQueryService> {
// onBlocking { findByUrl(eq(user.url)) } doReturn user
// }
// val activityPubNoteService = ApNoteJobServiceImpl(
//
// userQueryService = userQueryService,
// apRequestService = apRequestService,
// objectMapper = JsonObjectMapper.objectMapper,
// transaction = TestTransaction
// )
// val remoteUserOf = UserBuilder.remoteUserOf()
// activityPubNoteService.createNoteJob(
// JobProps(
// data = mapOf<String, Any>(
// DeliverPostJob.actor.name to user.url,
// DeliverPostJob.post.name to """{
// "id": 1,
// "userId": ${user.id},
// "text": "test text",
// "createdAt": 132525324,
// "visibility": 0,
// "url": "https://example.com"
// }""",
// DeliverPostJob.inbox.name to remoteUserOf.inbox,
// DeliverPostJob.media.name to "[]"
// ), json = Json
// )
// )
//
// val note = Note(
// name = "Note",
// id = "https://example.com",
// attributedTo = user.url,
// content = "test text",
// published = Instant.ofEpochMilli(132525324).toString(),
// to = listOfNotNull(APNoteServiceImpl.public, user.followers)
// )
// val create = Create(
// name = "Create Note",
// `object` = note,
// actor = note.attributedTo,
// id = "https://example.com/create/note/1"
// )
// verify(apRequestService, times(1)).apPost(
// eq(remoteUserOf.inbox),
// eq(create),
// eq(user)
// )
// }
}

View File

@ -18,18 +18,31 @@
package dev.usbharu.hideout.core.service.user
import dev.usbharu.hideout.activitypub.service.activity.delete.APSendDeleteService
import dev.usbharu.hideout.application.config.ApplicationConfig
import dev.usbharu.hideout.application.config.CharacterLimit
import dev.usbharu.hideout.core.domain.model.actor.Actor
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActorRepository
import dev.usbharu.hideout.core.domain.model.instance.Instance
import dev.usbharu.hideout.core.domain.model.post.PostRepository
import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.service.instance.InstanceService
import dev.usbharu.hideout.core.service.post.PostService
import dev.usbharu.owl.producer.api.OwlProducer
import jakarta.validation.Validation
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.ArgumentMatchers.anyString
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Spy
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.*
import utils.TestApplicationConfig.testApplicationConfig
import java.net.URL
@ -38,40 +51,65 @@ import java.time.Instant
import kotlin.test.assertEquals
import kotlin.test.assertNull
@ExtendWith(MockitoExtension::class)
class ActorServiceTest {
val actorBuilder = Actor.UserBuilder(
@Mock
private lateinit var actorRepository: ActorRepository
@Mock
private lateinit var userAuthService: UserAuthService
@Spy
private val actorBuilder = Actor.UserBuilder(
CharacterLimit(),
ApplicationConfig(URL("https://example.com")),
Validation.buildDefaultValidatorFactory().validator
)
@Spy
private val applicationConfig: ApplicationConfig = testApplicationConfig.copy(private = false)
@Mock
private lateinit var instanceService: InstanceService
@Mock
private lateinit var userDetailRepository: UserDetailRepository
@Mock
private lateinit var deletedActorRepository: DeletedActorRepository
@Mock
private lateinit var reactionRepository: ReactionRepository
@Mock
private lateinit var relationshipRepository: RelationshipRepository
@Mock
private lateinit var postService: PostService
@Mock
private lateinit var apSendDeleteService: APSendDeleteService
@Mock
private lateinit var postRepository: PostRepository
@Mock
private lateinit var owlProducer: OwlProducer
@InjectMocks
private lateinit var userService: UserServiceImpl
@Test
fun `createLocalUser ローカルユーザーを作成できる`() = runTest {
val actorRepository = mock<ActorRepository> {
onBlocking { nextId() } doReturn 110001L
}
val generateKeyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair()
val userAuthService = mock<UserAuthService> {
onBlocking { hash(anyString()) } doReturn "hashedPassword"
onBlocking { generateKeyPair() } doReturn generateKeyPair
}
val userService =
UserServiceImpl(
actorRepository = actorRepository,
userAuthService = userAuthService,
actorBuilder = actorBuilder,
applicationConfig = testApplicationConfig.copy(private = false),
instanceService = mock(),
userDetailRepository = mock(),
deletedActorRepository = mock(),
reactionRepository = mock(),
relationshipRepository = mock(),
postService = mock(),
apSendDeleteService = mock(),
postRepository = mock(),
owlProducer = mock()
)
whenever(actorRepository.nextId()).doReturn(110001L)
whenever(userAuthService.hash(anyString())).doReturn("hashedPassword")
whenever(userAuthService.generateKeyPair()).doReturn(generateKeyPair)
userService.createLocalUser(UserCreateDto("test", "testUser", "XXXXXXXXXXXXX", "test"))
verify(actorRepository, times(1)).save(any())
argumentCaptor<Actor> {
@ -91,31 +129,7 @@ class ActorServiceTest {
@Test
fun `createLocalUser applicationconfig privateがtrueのときアカウントを作成できない`() = runTest {
val actorRepository = mock<ActorRepository> {
onBlocking { nextId() } doReturn 110001L
}
val generateKeyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair()
val userAuthService = mock<UserAuthService> {
onBlocking { hash(anyString()) } doReturn "hashedPassword"
onBlocking { generateKeyPair() } doReturn generateKeyPair
}
val userService =
UserServiceImpl(
actorRepository = actorRepository,
userAuthService = userAuthService,
actorBuilder = actorBuilder,
applicationConfig = testApplicationConfig.copy(private = true),
instanceService = mock(),
userDetailRepository = mock(),
deletedActorRepository = mock(),
reactionRepository = mock(),
relationshipRepository = mock(),
postService = mock(),
apSendDeleteService = mock(),
postRepository = mock(),
owlProducer = mock()
)
whenever(applicationConfig.private).thenReturn(true)
assertThrows<IllegalStateException> {
userService.createLocalUser(UserCreateDto("test", "testUser", "XXXXXXXXXXXXX", "test"))
@ -126,17 +140,9 @@ class ActorServiceTest {
@Test
fun `createRemoteUser リモートユーザーを作成できる`() = runTest {
val actorRepository = mock<ActorRepository> {
onBlocking { nextId() } doReturn 113345L
}
val instanceService = mock<InstanceService> {
onBlocking {
fetchInstance(
eq("https://remote.example.com"),
isNull()
)
} doReturn Instance(
whenever(actorRepository.nextId()).doReturn(113345L)
whenever(instanceService.fetchInstance(eq("https://remote.example.com"), isNull())).doReturn(
Instance(
12345L,
"",
"",
@ -150,23 +156,8 @@ class ActorServiceTest {
"",
Instant.now()
)
}
val userService =
UserServiceImpl(
actorRepository = actorRepository,
userAuthService = mock(),
actorBuilder = actorBuilder,
applicationConfig = testApplicationConfig,
instanceService = instanceService,
userDetailRepository = mock(),
deletedActorRepository = mock(),
reactionRepository = mock(),
relationshipRepository = mock(),
postService = mock(),
apSendDeleteService = mock(),
postRepository = mock(),
owlProducer = mock()
)
)
val user = RemoteUserCreateDto(
name = "test",
domain = "remote.example.com",