mirror of https://github.com/usbharu/Hideout.git
test: APAcceptServiceImplのテストを追加
This commit is contained in:
parent
6dd9400113
commit
0e665dac34
|
@ -7,18 +7,78 @@ import io.ktor.http.*
|
||||||
sealed class ActivityPubResponse(
|
sealed class ActivityPubResponse(
|
||||||
val httpStatusCode: HttpStatusCode,
|
val httpStatusCode: HttpStatusCode,
|
||||||
val contentType: ContentType = ContentType.Application.Activity
|
val contentType: ContentType = ContentType.Application.Activity
|
||||||
)
|
) {
|
||||||
|
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is ActivityPubResponse) return false
|
||||||
|
|
||||||
|
if (httpStatusCode != other.httpStatusCode) return false
|
||||||
|
if (contentType != other.contentType) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = httpStatusCode.hashCode()
|
||||||
|
result = 31 * result + contentType.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "ActivityPubResponse(httpStatusCode=$httpStatusCode, contentType=$contentType)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ActivityPubStringResponse(
|
class ActivityPubStringResponse(
|
||||||
httpStatusCode: HttpStatusCode = HttpStatusCode.OK,
|
httpStatusCode: HttpStatusCode = HttpStatusCode.OK,
|
||||||
val message: String,
|
val message: String,
|
||||||
contentType: ContentType = ContentType.Application.Activity
|
contentType: ContentType = ContentType.Application.Activity
|
||||||
) :
|
) : ActivityPubResponse(httpStatusCode, contentType) {
|
||||||
ActivityPubResponse(httpStatusCode, contentType)
|
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is ActivityPubStringResponse) return false
|
||||||
|
|
||||||
|
if (message != other.message) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return message.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "ActivityPubStringResponse(message='$message') ${super.toString()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
class ActivityPubObjectResponse(
|
class ActivityPubObjectResponse(
|
||||||
httpStatusCode: HttpStatusCode = HttpStatusCode.OK,
|
httpStatusCode: HttpStatusCode = HttpStatusCode.OK,
|
||||||
val message: JsonLd,
|
val message: JsonLd,
|
||||||
contentType: ContentType = ContentType.Application.Activity
|
contentType: ContentType = ContentType.Application.Activity
|
||||||
) :
|
) : ActivityPubResponse(httpStatusCode, contentType) {
|
||||||
ActivityPubResponse(httpStatusCode, contentType)
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is ActivityPubObjectResponse) return false
|
||||||
|
|
||||||
|
if (message != other.message) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return message.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "ActivityPubObjectResponse(message=$message) ${super.toString()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
package dev.usbharu.hideout.service.ap
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.ActivityPubStringResponse
|
||||||
|
import dev.usbharu.hideout.domain.model.ap.Accept
|
||||||
|
import dev.usbharu.hideout.domain.model.ap.Follow
|
||||||
|
import dev.usbharu.hideout.domain.model.ap.Like
|
||||||
|
import dev.usbharu.hideout.exception.ap.IllegalActivityPubObjectException
|
||||||
|
import dev.usbharu.hideout.query.FollowerQueryService
|
||||||
|
import dev.usbharu.hideout.query.UserQueryService
|
||||||
|
import dev.usbharu.hideout.service.user.UserService
|
||||||
|
import io.ktor.http.*
|
||||||
|
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.mockito.kotlin.*
|
||||||
|
import utils.TestTransaction
|
||||||
|
import utils.UserBuilder
|
||||||
|
|
||||||
|
class APAcceptServiceImplTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `receiveAccept 正常なAcceptを処理できる`() = runTest {
|
||||||
|
val actor = "https://example.com"
|
||||||
|
val follower = "https://follower.example.com"
|
||||||
|
val targetUser = UserBuilder.localUserOf()
|
||||||
|
val followerUser = UserBuilder.localUserOf()
|
||||||
|
val userQueryService = mock<UserQueryService> {
|
||||||
|
onBlocking { findByUrl(eq(actor)) } doReturn targetUser
|
||||||
|
onBlocking { findByUrl(eq(follower)) } doReturn followerUser
|
||||||
|
}
|
||||||
|
val followerQueryService = mock<FollowerQueryService> {
|
||||||
|
onBlocking { alreadyFollow(eq(targetUser.id), eq(followerUser.id)) } doReturn false
|
||||||
|
}
|
||||||
|
val userService = mock<UserService>()
|
||||||
|
val apAcceptServiceImpl =
|
||||||
|
APAcceptServiceImpl(userService, userQueryService, followerQueryService, TestTransaction)
|
||||||
|
|
||||||
|
val accept = Accept(
|
||||||
|
name = "Accept",
|
||||||
|
`object` = Follow(
|
||||||
|
name = "",
|
||||||
|
`object` = actor,
|
||||||
|
actor = follower
|
||||||
|
),
|
||||||
|
actor = actor
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val actual = apAcceptServiceImpl.receiveAccept(accept)
|
||||||
|
assertEquals(ActivityPubStringResponse(HttpStatusCode.OK, "accepted"), actual)
|
||||||
|
verify(userService, times(1)).follow(eq(targetUser.id), eq(followerUser.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `receiveAccept 既にフォローしている場合は無視する`() = runTest {
|
||||||
|
|
||||||
|
val actor = "https://example.com"
|
||||||
|
val follower = "https://follower.example.com"
|
||||||
|
val targetUser = UserBuilder.localUserOf()
|
||||||
|
val followerUser = UserBuilder.localUserOf()
|
||||||
|
val userQueryService = mock<UserQueryService> {
|
||||||
|
onBlocking { findByUrl(eq(actor)) } doReturn targetUser
|
||||||
|
onBlocking { findByUrl(eq(follower)) } doReturn followerUser
|
||||||
|
}
|
||||||
|
val followerQueryService = mock<FollowerQueryService> {
|
||||||
|
onBlocking { alreadyFollow(eq(targetUser.id), eq(followerUser.id)) } doReturn true
|
||||||
|
}
|
||||||
|
val userService = mock<UserService>()
|
||||||
|
val apAcceptServiceImpl =
|
||||||
|
APAcceptServiceImpl(userService, userQueryService, followerQueryService, TestTransaction)
|
||||||
|
|
||||||
|
val accept = Accept(
|
||||||
|
name = "Accept",
|
||||||
|
`object` = Follow(
|
||||||
|
name = "",
|
||||||
|
`object` = actor,
|
||||||
|
actor = follower
|
||||||
|
),
|
||||||
|
actor = actor
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val actual = apAcceptServiceImpl.receiveAccept(accept)
|
||||||
|
assertEquals(ActivityPubStringResponse(HttpStatusCode.OK, "accepted"), actual)
|
||||||
|
verify(userService, times(0)).follow(eq(targetUser.id), eq(followerUser.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `revieveAccept AcceptのobjectのtypeがFollow以外の場合IllegalActivityPubObjectExceptionがthrowされる`() =
|
||||||
|
runTest {
|
||||||
|
val accept = Accept(
|
||||||
|
name = "Accept",
|
||||||
|
`object` = Like(
|
||||||
|
name = "Like",
|
||||||
|
actor = "actor",
|
||||||
|
id = "https://example.com",
|
||||||
|
`object` = "https://example.com",
|
||||||
|
content = "aaaa"
|
||||||
|
),
|
||||||
|
actor = "https://example.com"
|
||||||
|
)
|
||||||
|
|
||||||
|
val apAcceptServiceImpl = APAcceptServiceImpl(mock(), mock(), mock(), TestTransaction)
|
||||||
|
|
||||||
|
assertThrows<IllegalActivityPubObjectException> {
|
||||||
|
apAcceptServiceImpl.receiveAccept(accept)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.config.ApplicationConfig
|
||||||
|
import dev.usbharu.hideout.config.CharacterLimit
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
||||||
|
import dev.usbharu.hideout.service.core.TwitterSnowflakeIdGenerateService
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import java.net.URL
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
object UserBuilder {
|
||||||
|
private val userBuilder = User.UserBuilder(CharacterLimit(), ApplicationConfig(URL("https://example.com")))
|
||||||
|
|
||||||
|
private val idGenerator = TwitterSnowflakeIdGenerateService
|
||||||
|
|
||||||
|
suspend fun localUserOf(
|
||||||
|
id: Long = generateId(),
|
||||||
|
name: String = "test-user-$id",
|
||||||
|
domain: String = "example.com",
|
||||||
|
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/",
|
||||||
|
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"
|
||||||
|
): User {
|
||||||
|
return userBuilder.of(
|
||||||
|
id = id,
|
||||||
|
name = name,
|
||||||
|
domain = domain,
|
||||||
|
screenName = screenName,
|
||||||
|
description = description,
|
||||||
|
password = password,
|
||||||
|
inbox = inbox,
|
||||||
|
outbox = outbox,
|
||||||
|
url = url,
|
||||||
|
publicKey = publicKey,
|
||||||
|
privateKey = privateKey,
|
||||||
|
createdAt = createdAt,
|
||||||
|
keyId = keyId,
|
||||||
|
followers = following,
|
||||||
|
following = followers
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateId(): Long = runBlocking {
|
||||||
|
idGenerator.generateId()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue