test: テストを追加

This commit is contained in:
usbharu 2024-08-06 17:43:14 +09:00
parent c056b7598b
commit 0825be76b3
Signed by: usbharu
GPG Key ID: 6556747BF94EEBC8
11 changed files with 232 additions and 44 deletions

View File

@ -0,0 +1,5 @@
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
data class DeleteLocalActor(val actorId: ActorId)

View File

@ -1,37 +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.
*/
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import org.springframework.stereotype.Service
@Service
class DeleteLocalActorApplicationService(
private val transaction: Transaction,
private val actorRepository: ActorRepository,
) {
suspend fun delete(actorId: Long, executor: ActorId) {
transaction.transaction {
val id = ActorId(actorId)
val findById = actorRepository.findById(id)!!
findById.delete()
actorRepository.delete(findById)
}
}
}

View File

@ -16,6 +16,7 @@
package dev.usbharu.hideout.core.application.actor package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
@ -36,8 +37,9 @@ class GetUserDetailApplicationService(
AbstractApplicationService<GetUserDetail, UserDetail>(transaction, Companion.logger) { AbstractApplicationService<GetUserDetail, UserDetail>(transaction, Companion.logger) {
override suspend fun internalExecute(command: GetUserDetail, principal: Principal): UserDetail { override suspend fun internalExecute(command: GetUserDetail, principal: Principal): UserDetail {
val userDetail = userDetailRepository.findById(UserDetailId(command.id)) val userDetail = userDetailRepository.findById(UserDetailId(command.id))
?: throw IllegalArgumentException("actor does not exist") ?: throw IllegalArgumentException("User ${command.id} does not exist")
val actor = actorRepository.findById(userDetail.actorId)!! val actor = actorRepository.findById(userDetail.actorId)
?: throw InternalServerException("Actor ${userDetail.actorId} not found")
val emojis = customEmojiRepository.findByIds(actor.emojis.map { it.emojiId }) val emojis = customEmojiRepository.findByIds(actor.emojis.map { it.emojiId })

View File

@ -16,6 +16,7 @@
package dev.usbharu.hideout.core.application.actor package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.config.ApplicationConfig import dev.usbharu.hideout.core.config.ApplicationConfig
@ -49,9 +50,10 @@ class RegisterLocalActorApplicationService(
override suspend fun internalExecute(command: RegisterLocalActor, principal: Principal): URI { override suspend fun internalExecute(command: RegisterLocalActor, principal: Principal): URI {
if (actorDomainService.usernameAlreadyUse(command.name)) { if (actorDomainService.usernameAlreadyUse(command.name)) {
// todo 適切な例外を考える // todo 適切な例外を考える
throw Exception("Username already exists") throw IllegalArgumentException("Username already exists")
} }
val instance = instanceRepository.findByUrl(applicationConfig.url.toURI())!! val instance = instanceRepository.findByUrl(applicationConfig.url.toURI())
?: throw InternalServerException("Local instance not found.")
val actor = actorFactoryImpl.createLocal( val actor = actorFactoryImpl.createLocal(
command.name, command.name,

View File

@ -0,0 +1,46 @@
/*
* 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.
*/
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.support.principal.FromApi
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class StartDeleteLocalActorApplicationService(
transaction: Transaction,
private val actorRepository: ActorRepository,
) : LocalUserAbstractApplicationService<DeleteLocalActor, Unit>(transaction, logger) {
override suspend fun internalExecute(command: DeleteLocalActor, principal: FromApi) {
if (command.actorId != principal.actorId) {
throw PermissionDeniedException()
}
val findById = actorRepository.findById(command.actorId)
?: throw InternalServerException("Actor ${command.actorId} Not found")
findById.delete()
actorRepository.save(findById)
}
companion object {
private val logger = LoggerFactory.getLogger(StartDeleteLocalActorApplicationService::class.java)
}
}

View File

@ -30,8 +30,8 @@ class SuspendLocalActorApplicationService(
transaction.transaction { transaction.transaction {
val id = ActorId(actorId) val id = ActorId(actorId)
val findById = actorRepository.findById(id)!! val actor = actorRepository.findById(id)!!
findById.suspend = true actor.suspend = true
} }
} }
} }

View File

@ -0,0 +1,14 @@
package dev.usbharu.hideout.core.application.exception
class InternalServerException : RuntimeException {
constructor() : super()
constructor(message: String?) : super(message)
constructor(message: String?, cause: Throwable?) : super(message, cause)
constructor(cause: Throwable?) : super(cause)
constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super(
message,
cause,
enableSuppression,
writableStackTrace
)
}

View File

@ -0,0 +1,14 @@
package dev.usbharu.hideout.core.application.exception
class PermissionDeniedException : RuntimeException {
constructor() : super()
constructor(message: String?) : super(message)
constructor(message: String?, cause: Throwable?) : super(message, cause)
constructor(cause: Throwable?) : super(cause)
constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super(
message,
cause,
enableSuppression,
writableStackTrace
)
}

View File

@ -11,5 +11,5 @@ abstract class LocalUserAbstractApplicationService<T : Any, R>(transaction: Tran
return internalExecute(command, principal) return internalExecute(command, principal)
} }
abstract suspend fun internalExecute(command: T, principal: FromApi): R protected abstract suspend fun internalExecute(command: T, principal: FromApi): R
} }

View File

@ -0,0 +1,78 @@
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.actor.TestActorFactory
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository
import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailHashedPassword
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
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.InjectMocks
import org.mockito.Mock
import org.mockito.Spy
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.whenever
import utils.TestTransaction
@ExtendWith(MockitoExtension::class)
class GetUserDetailApplicationServiceTest {
@InjectMocks
lateinit var service: GetUserDetailApplicationService
@Mock
lateinit var actorRepository: ActorRepository
@Mock
lateinit var userDetailRepository: UserDetailRepository
@Mock
lateinit var customEmojiRepository: CustomEmojiRepository
@Spy
val transaction = TestTransaction
@Test
fun userDetailを取得できる() = runTest {
whenever(userDetailRepository.findById(UserDetailId(1))).doReturn(
UserDetail.create(
UserDetailId(1), ActorId(1),
UserDetailHashedPassword("")
)
)
whenever(actorRepository.findById(ActorId(1))).doReturn(TestActorFactory.create(1))
whenever(customEmojiRepository.findByIds(any())).doReturn(listOf())
service.execute(GetUserDetail(1), Anonymous)
}
@Test
fun userDetailが存在しない場合失敗() = runTest {
assertThrows<IllegalArgumentException> {
service.execute(GetUserDetail(2), Anonymous)
}
}
@Test
fun userDetailが存在するけどActorが存在しない場合はInternalServerException() = runTest {
whenever(userDetailRepository.findById(UserDetailId(2))).doReturn(
UserDetail.create(
UserDetailId(2), ActorId(2),
UserDetailHashedPassword("")
)
)
assertThrows<InternalServerException> {
service.execute(GetUserDetail(2), Anonymous)
}
}
}

View File

@ -0,0 +1,64 @@
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.actor.TestActorFactory
import dev.usbharu.hideout.core.domain.model.support.acct.Acct
import dev.usbharu.hideout.core.domain.model.support.principal.FromApi
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
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.InjectMocks
import org.mockito.Mock
import org.mockito.Spy
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.whenever
import utils.TestTransaction
@ExtendWith(MockitoExtension::class)
class StartDeleteLocalActorApplicationServiceTest {
@InjectMocks
lateinit var service: StartDeleteLocalActorApplicationService
@Mock
lateinit var actorRepository: ActorRepository
@Spy
val transaction = TestTransaction
@Test
fun ローカルActorを削除できる() = runTest {
whenever(actorRepository.findById(ActorId(1))).doReturn(TestActorFactory.create(1))
service.execute(
DeleteLocalActor(ActorId(1)),
FromApi(ActorId(1), UserDetailId((1)), Acct("test", "example.com"))
)
}
@Test
fun ログイン中のユーザーと一致しない場合失敗() = runTest {
assertThrows<PermissionDeniedException> {
service.execute(
DeleteLocalActor(ActorId(2)),
FromApi(ActorId(1), UserDetailId((1)), Acct("test", "example.com"))
)
}
}
@Test
fun ユーザーが存在しない場合失敗() = runTest {
assertThrows<InternalServerException> {
service.execute(
DeleteLocalActor(ActorId(1)),
FromApi(ActorId(1), UserDetailId((1)), Acct("test", "example.com"))
)
}
}
}