refactor: ActivityPubStringResponseを削除

This commit is contained in:
usbharu 2023-11-22 00:27:44 +09:00
parent 986d16f442
commit cedebb794b
14 changed files with 25 additions and 120 deletions

View File

@ -1,68 +0,0 @@
package dev.usbharu.hideout.activitypub.interfaces.api.common
import dev.usbharu.hideout.activitypub.domain.model.JsonLd
import dev.usbharu.hideout.util.HttpUtil.Activity
import io.ktor.http.*
sealed class ActivityPubResponse(
val httpStatusCode: HttpStatusCode,
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 = "ActivityPubResponse(httpStatusCode=$httpStatusCode, contentType=$contentType)"
}
class ActivityPubStringResponse(
httpStatusCode: HttpStatusCode = HttpStatusCode.OK,
val message: String,
contentType: ContentType = ContentType.Application.Activity
) : 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 = message.hashCode()
override fun toString(): String = "ActivityPubStringResponse(message='$message') ${super.toString()}"
}
class ActivityPubObjectResponse(
httpStatusCode: HttpStatusCode = HttpStatusCode.OK,
val message: JsonLd,
contentType: ContentType = ContentType.Application.Activity
) : 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 = message.hashCode()
override fun toString(): String = "ActivityPubObjectResponse(message=$message) ${super.toString()}"
}

View File

@ -3,18 +3,15 @@ package dev.usbharu.hideout.activitypub.service.activity.accept
import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException
import dev.usbharu.hideout.activitypub.domain.model.Accept import dev.usbharu.hideout.activitypub.domain.model.Accept
import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.domain.model.Follow
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse
import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.application.external.Transaction
import dev.usbharu.hideout.core.query.FollowerQueryService import dev.usbharu.hideout.core.query.FollowerQueryService
import dev.usbharu.hideout.core.query.UserQueryService import dev.usbharu.hideout.core.query.UserQueryService
import dev.usbharu.hideout.core.service.user.UserService import dev.usbharu.hideout.core.service.user.UserService
import io.ktor.http.*
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
interface APAcceptService { interface APAcceptService {
suspend fun receiveAccept(accept: Accept): ActivityPubResponse suspend fun receiveAccept(accept: Accept)
} }
@Service @Service
@ -24,7 +21,7 @@ class APAcceptServiceImpl(
private val followerQueryService: FollowerQueryService, private val followerQueryService: FollowerQueryService,
private val transaction: Transaction private val transaction: Transaction
) : APAcceptService { ) : APAcceptService {
override suspend fun receiveAccept(accept: Accept): ActivityPubResponse { override suspend fun receiveAccept(accept: Accept) {
return transaction.transaction { return transaction.transaction {
LOGGER.debug("START Follow") LOGGER.debug("START Follow")
LOGGER.trace("{}", accept) LOGGER.trace("{}", accept)
@ -43,11 +40,11 @@ class APAcceptServiceImpl(
if (followerQueryService.alreadyFollow(user.id, follower.id)) { if (followerQueryService.alreadyFollow(user.id, follower.id)) {
LOGGER.debug("END User already follow from ${follower.url} to ${user.url}") LOGGER.debug("END User already follow from ${follower.url} to ${user.url}")
return@transaction ActivityPubStringResponse(HttpStatusCode.OK, "accepted") return@transaction
} }
userService.follow(user.id, follower.id) userService.follow(user.id, follower.id)
LOGGER.debug("SUCCESS Follow from ${follower.url} to ${user.url}.") LOGGER.debug("SUCCESS Follow from ${follower.url} to ${user.url}.")
ActivityPubStringResponse(HttpStatusCode.OK, "accepted")
} }
} }

View File

@ -3,16 +3,13 @@ package dev.usbharu.hideout.activitypub.service.activity.create
import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException
import dev.usbharu.hideout.activitypub.domain.model.Create import dev.usbharu.hideout.activitypub.domain.model.Create
import dev.usbharu.hideout.activitypub.domain.model.Note import dev.usbharu.hideout.activitypub.domain.model.Note
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse
import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService
import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.application.external.Transaction
import io.ktor.http.*
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
interface APCreateService { interface APCreateService {
suspend fun receiveCreate(create: Create): ActivityPubResponse suspend fun receiveCreate(create: Create)
} }
@Service @Service
@ -20,7 +17,7 @@ class APCreateServiceImpl(
private val apNoteService: APNoteService, private val apNoteService: APNoteService,
private val transaction: Transaction private val transaction: Transaction
) : APCreateService { ) : APCreateService {
override suspend fun receiveCreate(create: Create): ActivityPubResponse { override suspend fun receiveCreate(create: Create) {
LOGGER.debug("START Create new remote note.") LOGGER.debug("START Create new remote note.")
LOGGER.trace("{}", create) LOGGER.trace("{}", create)
@ -34,7 +31,6 @@ class APCreateServiceImpl(
val note = value as Note val note = value as Note
apNoteService.fetchNote(note) apNoteService.fetchNote(note)
LOGGER.debug("SUCCESS Create new remote note. ${note.id} by ${note.attributedTo}") LOGGER.debug("SUCCESS Create new remote note. ${note.id} by ${note.attributedTo}")
ActivityPubStringResponse(HttpStatusCode.OK, "Created")
} }
} }

View File

@ -1,8 +1,7 @@
package dev.usbharu.hideout.activitypub.service.activity.delete package dev.usbharu.hideout.activitypub.service.activity.delete
import dev.usbharu.hideout.activitypub.domain.model.Delete import dev.usbharu.hideout.activitypub.domain.model.Delete
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse
interface APReceiveDeleteService { interface APReceiveDeleteService {
suspend fun receiveDelete(delete: Delete): ActivityPubResponse suspend fun receiveDelete(delete: Delete)
} }

View File

@ -2,13 +2,10 @@ package dev.usbharu.hideout.activitypub.service.activity.delete
import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException
import dev.usbharu.hideout.activitypub.domain.model.Delete import dev.usbharu.hideout.activitypub.domain.model.Delete
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse
import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.application.external.Transaction
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException
import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.post.PostRepository
import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.query.PostQueryService
import io.ktor.http.*
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
@Service @Service
@ -17,15 +14,15 @@ class APReceiveDeleteServiceImpl(
private val postRepository: PostRepository, private val postRepository: PostRepository,
private val transaction: Transaction private val transaction: Transaction
) : APReceiveDeleteService { ) : APReceiveDeleteService {
override suspend fun receiveDelete(delete: Delete): ActivityPubResponse = transaction.transaction { override suspend fun receiveDelete(delete: Delete) = transaction.transaction {
val deleteId = delete.`object`?.id ?: throw IllegalActivityPubObjectException("object.id is null") val deleteId = delete.`object`?.id ?: throw IllegalActivityPubObjectException("object.id is null")
val post = try { val post = try {
postQueryService.findByApId(deleteId) postQueryService.findByApId(deleteId)
} catch (_: FailedToGetResourcesException) { } catch (_: FailedToGetResourcesException) {
return@transaction ActivityPubStringResponse(HttpStatusCode.OK, "Resource not found or already deleted") return@transaction
} }
postRepository.delete(post.id) postRepository.delete(post.id)
return@transaction ActivityPubStringResponse(HttpStatusCode.OK, "Resource was deleted.") return@transaction
} }
} }

View File

@ -2,17 +2,14 @@ package dev.usbharu.hideout.activitypub.service.activity.follow
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.domain.model.Follow
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse
import dev.usbharu.hideout.core.external.job.ReceiveFollowJob import dev.usbharu.hideout.core.external.job.ReceiveFollowJob
import dev.usbharu.hideout.core.service.job.JobQueueParentService import dev.usbharu.hideout.core.service.job.JobQueueParentService
import io.ktor.http.*
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Qualifier import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
interface APReceiveFollowService { interface APReceiveFollowService {
suspend fun receiveFollow(follow: Follow): ActivityPubResponse suspend fun receiveFollow(follow: Follow)
} }
@Service @Service
@ -20,14 +17,14 @@ class APReceiveFollowServiceImpl(
private val jobQueueParentService: JobQueueParentService, private val jobQueueParentService: JobQueueParentService,
@Qualifier("activitypub") private val objectMapper: ObjectMapper @Qualifier("activitypub") private val objectMapper: ObjectMapper
) : APReceiveFollowService { ) : APReceiveFollowService {
override suspend fun receiveFollow(follow: Follow): ActivityPubResponse { override suspend fun receiveFollow(follow: Follow) {
logger.info("FOLLOW from: {} to: {}", follow.actor, follow.`object`) logger.info("FOLLOW from: {} to: {}", follow.actor, follow.`object`)
jobQueueParentService.schedule(ReceiveFollowJob) { jobQueueParentService.schedule(ReceiveFollowJob) {
props[ReceiveFollowJob.actor] = follow.actor props[ReceiveFollowJob.actor] = follow.actor
props[ReceiveFollowJob.follow] = objectMapper.writeValueAsString(follow) props[ReceiveFollowJob.follow] = objectMapper.writeValueAsString(follow)
props[ReceiveFollowJob.targetActor] = follow.`object` props[ReceiveFollowJob.targetActor] = follow.`object`
} }
return ActivityPubStringResponse(HttpStatusCode.OK, "{}", ContentType.Application.Json) return
} }
companion object { companion object {

View File

@ -3,19 +3,16 @@ package dev.usbharu.hideout.activitypub.service.activity.like
import dev.usbharu.hideout.activitypub.domain.exception.FailedToGetActivityPubResourceException import dev.usbharu.hideout.activitypub.domain.exception.FailedToGetActivityPubResourceException
import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException
import dev.usbharu.hideout.activitypub.domain.model.Like import dev.usbharu.hideout.activitypub.domain.model.Like
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse
import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService
import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.activitypub.service.objects.user.APUserService
import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.application.external.Transaction
import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.query.PostQueryService
import dev.usbharu.hideout.core.service.reaction.ReactionService import dev.usbharu.hideout.core.service.reaction.ReactionService
import io.ktor.http.*
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
interface APLikeService { interface APLikeService {
suspend fun receiveLike(like: Like): ActivityPubResponse suspend fun receiveLike(like: Like)
} }
@Service @Service
@ -26,7 +23,7 @@ class APLikeServiceImpl(
private val postQueryService: PostQueryService, private val postQueryService: PostQueryService,
private val transaction: Transaction private val transaction: Transaction
) : APLikeService { ) : APLikeService {
override suspend fun receiveLike(like: Like): ActivityPubResponse { override suspend fun receiveLike(like: Like) {
LOGGER.debug("START Add Like") LOGGER.debug("START Add Like")
LOGGER.trace("{}", like) LOGGER.trace("{}", like)
@ -57,7 +54,7 @@ class APLikeServiceImpl(
) )
LOGGER.debug("SUCCESS Add Like($content) from ${person.second.url} to ${post.url}") LOGGER.debug("SUCCESS Add Like($content) from ${person.second.url} to ${post.url}")
} }
return ActivityPubStringResponse(HttpStatusCode.OK, "") return
} }
companion object { companion object {

View File

@ -2,17 +2,14 @@ package dev.usbharu.hideout.activitypub.service.activity.undo
import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.domain.model.Follow
import dev.usbharu.hideout.activitypub.domain.model.Undo import dev.usbharu.hideout.activitypub.domain.model.Undo
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse
import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.activitypub.service.objects.user.APUserService
import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.application.external.Transaction
import dev.usbharu.hideout.core.query.UserQueryService import dev.usbharu.hideout.core.query.UserQueryService
import dev.usbharu.hideout.core.service.user.UserService import dev.usbharu.hideout.core.service.user.UserService
import io.ktor.http.*
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
interface APUndoService { interface APUndoService {
suspend fun receiveUndo(undo: Undo): ActivityPubResponse suspend fun receiveUndo(undo: Undo)
} }
@Service @Service
@ -23,22 +20,22 @@ class APUndoServiceImpl(
private val userQueryService: UserQueryService, private val userQueryService: UserQueryService,
private val transaction: Transaction private val transaction: Transaction
) : APUndoService { ) : APUndoService {
override suspend fun receiveUndo(undo: Undo): ActivityPubResponse { override suspend fun receiveUndo(undo: Undo) {
if (undo.actor == null) { if (undo.actor == null) {
return ActivityPubStringResponse(HttpStatusCode.BadRequest, "actor is null") return
} }
val type = val type =
undo.`object`?.type.orEmpty() undo.`object`?.type.orEmpty()
.firstOrNull { it == "Block" || it == "Follow" || it == "Like" || it == "Announce" || it == "Accept" } .firstOrNull { it == "Block" || it == "Follow" || it == "Like" || it == "Announce" || it == "Accept" }
?: return ActivityPubStringResponse(HttpStatusCode.BadRequest, "unknown type ${undo.`object`?.type}") ?: return
when (type) { when (type) {
"Follow" -> { "Follow" -> {
val follow = undo.`object` as Follow val follow = undo.`object` as Follow
if (follow.`object` == null) { if (follow.`object` == null) {
return ActivityPubStringResponse(HttpStatusCode.BadRequest, "object.object is null") return
} }
transaction.transaction { transaction.transaction {
apUserService.fetchPerson(undo.actor!!, follow.`object`) apUserService.fetchPerson(undo.actor!!, follow.`object`)
@ -46,7 +43,7 @@ class APUndoServiceImpl(
val target = userQueryService.findByUrl(follow.`object`!!) val target = userQueryService.findByUrl(follow.`object`!!)
userService.unfollow(target.id, follower.id) userService.unfollow(target.id, follower.id)
} }
return ActivityPubStringResponse(HttpStatusCode.OK, "Accept") return
} }
else -> {} else -> {}

View File

@ -3,8 +3,6 @@ package dev.usbharu.hideout.activitypub.service.common
import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import dev.usbharu.hideout.activitypub.domain.exception.JsonParseException import dev.usbharu.hideout.activitypub.domain.exception.JsonParseException
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse
import dev.usbharu.hideout.core.external.job.InboxJob import dev.usbharu.hideout.core.external.job.InboxJob
import dev.usbharu.hideout.core.service.job.JobQueueParentService import dev.usbharu.hideout.core.service.job.JobQueueParentService
import dev.usbharu.httpsignature.common.HttpRequest import dev.usbharu.httpsignature.common.HttpRequest
@ -21,7 +19,7 @@ interface APService {
type: ActivityType, type: ActivityType,
httpRequest: HttpRequest, httpRequest: HttpRequest,
map: Map<String, List<String>> map: Map<String, List<String>>
): ActivityPubResponse? )
} }
enum class ActivityType { enum class ActivityType {
@ -226,7 +224,7 @@ class APServiceImpl(
type: ActivityType, type: ActivityType,
httpRequest: HttpRequest, httpRequest: HttpRequest,
map: Map<String, List<String>> map: Map<String, List<String>>
): ActivityPubResponse { ) {
logger.debug("process activity: {}", type) logger.debug("process activity: {}", type)
jobQueueParentService.schedule(InboxJob) { jobQueueParentService.schedule(InboxJob) {
props[it.json] = json props[it.json] = json
@ -236,6 +234,6 @@ class APServiceImpl(
props[it.httpRequest] = writeValueAsString props[it.httpRequest] = writeValueAsString
props[it.headers] = objectMapper.writeValueAsString(map) props[it.headers] = objectMapper.writeValueAsString(map)
} }
return ActivityPubStringResponse(message = "") return
} }
} }

View File

@ -1,7 +1,6 @@
package dev.usbharu.hideout.activitypub.interfaces.api.inbox package dev.usbharu.hideout.activitypub.interfaces.api.inbox
import dev.usbharu.hideout.activitypub.domain.exception.JsonParseException import dev.usbharu.hideout.activitypub.domain.exception.JsonParseException
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse
import dev.usbharu.hideout.activitypub.service.common.APService import dev.usbharu.hideout.activitypub.service.common.APService
import dev.usbharu.hideout.activitypub.service.common.ActivityType import dev.usbharu.hideout.activitypub.service.common.ActivityType
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException

View File

@ -4,7 +4,6 @@ import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObject
import dev.usbharu.hideout.activitypub.domain.model.Accept import dev.usbharu.hideout.activitypub.domain.model.Accept
import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.domain.model.Follow
import dev.usbharu.hideout.activitypub.domain.model.Like import dev.usbharu.hideout.activitypub.domain.model.Like
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse
import dev.usbharu.hideout.core.query.FollowerQueryService import dev.usbharu.hideout.core.query.FollowerQueryService
import dev.usbharu.hideout.core.query.UserQueryService import dev.usbharu.hideout.core.query.UserQueryService
import dev.usbharu.hideout.core.service.user.UserService import dev.usbharu.hideout.core.service.user.UserService

View File

@ -4,7 +4,6 @@ import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObject
import dev.usbharu.hideout.activitypub.domain.model.Create import dev.usbharu.hideout.activitypub.domain.model.Create
import dev.usbharu.hideout.activitypub.domain.model.Like import dev.usbharu.hideout.activitypub.domain.model.Like
import dev.usbharu.hideout.activitypub.domain.model.Note import dev.usbharu.hideout.activitypub.domain.model.Note
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse
import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService
import io.ktor.http.* import io.ktor.http.*
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest

View File

@ -4,7 +4,6 @@ import dev.usbharu.hideout.activitypub.domain.exception.FailedToGetActivityPubRe
import dev.usbharu.hideout.activitypub.domain.model.Like import dev.usbharu.hideout.activitypub.domain.model.Like
import dev.usbharu.hideout.activitypub.domain.model.Note import dev.usbharu.hideout.activitypub.domain.model.Note
import dev.usbharu.hideout.activitypub.domain.model.Person import dev.usbharu.hideout.activitypub.domain.model.Person
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse
import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService
import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.activitypub.service.objects.user.APUserService
import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.query.PostQueryService

View File

@ -2,7 +2,6 @@ package dev.usbharu.hideout.activitypub.service.activity.undo
import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.domain.model.Follow
import dev.usbharu.hideout.activitypub.domain.model.Undo import dev.usbharu.hideout.activitypub.domain.model.Undo
import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse
import dev.usbharu.hideout.core.query.UserQueryService import dev.usbharu.hideout.core.query.UserQueryService
import io.ktor.http.* import io.ktor.http.*
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest