mirror of https://github.com/usbharu/Hideout.git
feat: Undoを実装
This commit is contained in:
parent
fbff97c247
commit
cb2ee6ca3f
|
@ -6,6 +6,6 @@ exposed_version=0.41.1
|
||||||
h2_version=2.1.214
|
h2_version=2.1.214
|
||||||
koin_version=3.3.1
|
koin_version=3.3.1
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
org.gradle.configureondemand=true
|
#org.gradle.configureondemand=true
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
org.gradle.jvmargs=-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC
|
org.gradle.jvmargs=-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC
|
||||||
|
|
|
@ -1,33 +1,43 @@
|
||||||
package dev.usbharu.hideout.domain.model.ap
|
package dev.usbharu.hideout.domain.model.ap
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
|
||||||
|
|
||||||
open class Accept : Object {
|
open class Accept : Object {
|
||||||
|
@JsonDeserialize(using = ObjectDeserializer::class)
|
||||||
var `object`: Object? = null
|
var `object`: Object? = null
|
||||||
|
|
||||||
protected constructor() : super()
|
protected constructor()
|
||||||
constructor(
|
constructor(
|
||||||
type: List<String> = emptyList(),
|
type: List<String> = emptyList(),
|
||||||
name: String,
|
name: String,
|
||||||
`object`: Object?,
|
`object`: Object?,
|
||||||
actor: String?
|
actor: String?
|
||||||
) : super(add(type, "Accept"), name, actor) {
|
) : super(
|
||||||
|
type = add(type, "Accept"),
|
||||||
|
name = name,
|
||||||
|
actor = actor
|
||||||
|
) {
|
||||||
this.`object` = `object`
|
this.`object` = `object`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "Accept(`object`=$`object`) ${super.toString()}"
|
||||||
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other !is Accept) return false
|
if (other !is Accept) return false
|
||||||
if (!super.equals(other)) return false
|
if (!super.equals(other)) return false
|
||||||
|
|
||||||
if (`object` != other.`object`) return false
|
return `object` == other.`object`
|
||||||
return actor == other.actor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
var result = super.hashCode()
|
var result = super.hashCode()
|
||||||
result = 31 * result + (`object`?.hashCode() ?: 0)
|
result = 31 * result + (`object`?.hashCode() ?: 0)
|
||||||
result = 31 * result + (actor?.hashCode() ?: 0)
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = "Accept(`object`=$`object`, actor=$actor) ${super.toString()}"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ open class Follow : Object {
|
||||||
protected constructor() : super()
|
protected constructor() : super()
|
||||||
constructor(
|
constructor(
|
||||||
type: List<String> = emptyList(),
|
type: List<String> = emptyList(),
|
||||||
name: String,
|
name: String?,
|
||||||
`object`: String?,
|
`object`: String?,
|
||||||
actor: String?
|
actor: String?
|
||||||
) : super(
|
) : super(
|
||||||
|
@ -16,4 +16,24 @@ open class Follow : Object {
|
||||||
) {
|
) {
|
||||||
this.`object` = `object`
|
this.`object` = `object`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is Follow) return false
|
||||||
|
if (!super.equals(other)) return false
|
||||||
|
|
||||||
|
return `object` == other.`object`
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = super.hashCode()
|
||||||
|
result = 31 * result + (`object`?.hashCode() ?: 0)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "Follow(`object`=$`object`) ${super.toString()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize
|
||||||
|
|
||||||
open class Object : JsonLd {
|
open class Object : JsonLd {
|
||||||
@JsonSerialize(using = TypeSerializer::class)
|
@JsonSerialize(using = TypeSerializer::class)
|
||||||
private var type: List<String> = emptyList()
|
var type: List<String> = emptyList()
|
||||||
var name: String? = null
|
var name: String? = null
|
||||||
var actor: String? = null
|
var actor: String? = null
|
||||||
var id: String? = null
|
var id: String? = null
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package dev.usbharu.hideout.domain.model.ap
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParser
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode
|
||||||
|
import dev.usbharu.hideout.service.activitypub.ActivityType
|
||||||
|
|
||||||
|
class ObjectDeserializer : JsonDeserializer<Object>() {
|
||||||
|
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Object {
|
||||||
|
requireNotNull(p)
|
||||||
|
val treeNode: JsonNode = requireNotNull(p.codec?.readTree(p))
|
||||||
|
if (treeNode.isValueNode) {
|
||||||
|
return ObjectValue(
|
||||||
|
emptyList(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
treeNode.asText()
|
||||||
|
)
|
||||||
|
} else if (treeNode.isObject) {
|
||||||
|
val type = treeNode["type"]
|
||||||
|
val activityType = if (type.isArray) {
|
||||||
|
type.firstNotNullOf { jsonNode: JsonNode ->
|
||||||
|
ActivityType.values().firstOrNull { it.name.equals(jsonNode.asText(), true) }
|
||||||
|
}
|
||||||
|
} else if (type.isValueNode) {
|
||||||
|
ActivityType.values().first { it.name.equals(type.asText(), true) }
|
||||||
|
} else {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (activityType) {
|
||||||
|
ActivityType.Follow -> {
|
||||||
|
val readValue = p.codec.treeToValue(treeNode, Follow::class.java)
|
||||||
|
println(readValue)
|
||||||
|
readValue
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package dev.usbharu.hideout.domain.model.ap
|
||||||
|
|
||||||
|
class ObjectValue : Object {
|
||||||
|
|
||||||
|
var `object`: String? = null
|
||||||
|
|
||||||
|
protected constructor()
|
||||||
|
constructor(type: List<String>, name: String?, actor: String?, id: String?, `object`: String?) : super(
|
||||||
|
type,
|
||||||
|
name,
|
||||||
|
actor,
|
||||||
|
id
|
||||||
|
) {
|
||||||
|
this.`object` = `object`
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is ObjectValue) return false
|
||||||
|
if (!super.equals(other)) return false
|
||||||
|
|
||||||
|
return `object` == other.`object`
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = super.hashCode()
|
||||||
|
result = 31 * result + (`object`?.hashCode() ?: 0)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "ObjectValue(`object`=$`object`) ${super.toString()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package dev.usbharu.hideout.domain.model.ap
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
class Undo : Object {
|
||||||
|
|
||||||
|
@JsonDeserialize(using = ObjectDeserializer::class)
|
||||||
|
var `object`: Object? = null
|
||||||
|
var published: String? = null
|
||||||
|
|
||||||
|
protected constructor()
|
||||||
|
constructor(
|
||||||
|
type: List<String> = emptyList(),
|
||||||
|
name: String,
|
||||||
|
actor: String,
|
||||||
|
id: String?,
|
||||||
|
`object`: Object,
|
||||||
|
published: Instant
|
||||||
|
) : super(add(type, "Undo"), name, actor, id) {
|
||||||
|
this.`object` = `object`
|
||||||
|
this.published = published.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is Undo) return false
|
||||||
|
if (!super.equals(other)) return false
|
||||||
|
|
||||||
|
if (`object` != other.`object`) return false
|
||||||
|
return published == other.published
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = super.hashCode()
|
||||||
|
result = 31 * result + (`object`?.hashCode() ?: 0)
|
||||||
|
result = 31 * result + (published?.hashCode() ?: 0)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "Undo(`object`=$`object`, published=$published) ${super.toString()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -71,7 +71,7 @@ fun Route.users(userService: IUserService, userApiService: IUserApiService) {
|
||||||
val userParameter = call.parameters["name"]
|
val userParameter = call.parameters["name"]
|
||||||
?: throw ParameterNotExistException("Parameter(name='userName@domain') does not exist.")
|
?: throw ParameterNotExistException("Parameter(name='userName@domain') does not exist.")
|
||||||
if (userParameter.toLongOrNull() != null) {
|
if (userParameter.toLongOrNull() != null) {
|
||||||
if (userService.addFollowers(userParameter.toLong(), userId)) {
|
if (userService.follow(userParameter.toLong(), userId)) {
|
||||||
return@post call.respond(HttpStatusCode.OK)
|
return@post call.respond(HttpStatusCode.OK)
|
||||||
} else {
|
} else {
|
||||||
return@post call.respond(HttpStatusCode.Accepted)
|
return@post call.respond(HttpStatusCode.Accepted)
|
||||||
|
@ -79,7 +79,7 @@ fun Route.users(userService: IUserService, userApiService: IUserApiService) {
|
||||||
}
|
}
|
||||||
val acct = AcctUtil.parse(userParameter)
|
val acct = AcctUtil.parse(userParameter)
|
||||||
val targetUser = userApiService.findByAcct(acct)
|
val targetUser = userApiService.findByAcct(acct)
|
||||||
if (userService.addFollowers(targetUser.id, userId)) {
|
if (userService.follow(targetUser.id, userId)) {
|
||||||
return@post call.respond(HttpStatusCode.OK)
|
return@post call.respond(HttpStatusCode.OK)
|
||||||
} else {
|
} else {
|
||||||
return@post call.respond(HttpStatusCode.Accepted)
|
return@post call.respond(HttpStatusCode.Accepted)
|
||||||
|
|
|
@ -49,6 +49,6 @@ class ActivityPubFollowServiceImpl(
|
||||||
val users =
|
val users =
|
||||||
userService.findByUrls(listOf(targetActor, follow.actor ?: throw IllegalArgumentException("actor is null")))
|
userService.findByUrls(listOf(targetActor, follow.actor ?: throw IllegalArgumentException("actor is null")))
|
||||||
|
|
||||||
userService.addFollowers(users.first { it.url == targetActor }.id, users.first { it.url == follow.actor }.id)
|
userService.follow(users.first { it.url == targetActor }.id, users.first { it.url == follow.actor }.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package dev.usbharu.hideout.service.activitypub
|
package dev.usbharu.hideout.service.activitypub
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode
|
import com.fasterxml.jackson.databind.JsonNode
|
||||||
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import dev.usbharu.hideout.config.Config
|
import dev.usbharu.hideout.config.Config
|
||||||
import dev.usbharu.hideout.domain.model.ActivityPubResponse
|
import dev.usbharu.hideout.domain.model.ActivityPubResponse
|
||||||
import dev.usbharu.hideout.domain.model.ap.Follow
|
import dev.usbharu.hideout.domain.model.ap.Follow
|
||||||
|
@ -17,7 +18,8 @@ import org.slf4j.LoggerFactory
|
||||||
@Single
|
@Single
|
||||||
class ActivityPubServiceImpl(
|
class ActivityPubServiceImpl(
|
||||||
private val activityPubFollowService: ActivityPubFollowService,
|
private val activityPubFollowService: ActivityPubFollowService,
|
||||||
private val activityPubNoteService: ActivityPubNoteService
|
private val activityPubNoteService: ActivityPubNoteService,
|
||||||
|
private val activityPubUndoService: ActivityPubUndoService
|
||||||
) : ActivityPubService {
|
) : ActivityPubService {
|
||||||
|
|
||||||
val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
||||||
|
@ -70,7 +72,7 @@ class ActivityPubServiceImpl(
|
||||||
ActivityType.TentativeReject -> TODO()
|
ActivityType.TentativeReject -> TODO()
|
||||||
ActivityType.TentativeAccept -> TODO()
|
ActivityType.TentativeAccept -> TODO()
|
||||||
ActivityType.Travel -> TODO()
|
ActivityType.Travel -> TODO()
|
||||||
ActivityType.Undo -> TODO()
|
ActivityType.Undo -> activityPubUndoService.receiveUndo(Config.configData.objectMapper.readValue(json))
|
||||||
ActivityType.Update -> TODO()
|
ActivityType.Update -> TODO()
|
||||||
ActivityType.View -> TODO()
|
ActivityType.View -> TODO()
|
||||||
ActivityType.Other -> TODO()
|
ActivityType.Other -> TODO()
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package dev.usbharu.hideout.service.activitypub
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.ActivityPubResponse
|
||||||
|
import dev.usbharu.hideout.domain.model.ap.Undo
|
||||||
|
|
||||||
|
interface ActivityPubUndoService {
|
||||||
|
suspend fun receiveUndo(undo: Undo): ActivityPubResponse
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package dev.usbharu.hideout.service.activitypub
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.ActivityPubResponse
|
||||||
|
import dev.usbharu.hideout.domain.model.ActivityPubStringResponse
|
||||||
|
import dev.usbharu.hideout.domain.model.ap.Follow
|
||||||
|
import dev.usbharu.hideout.domain.model.ap.Undo
|
||||||
|
import dev.usbharu.hideout.service.impl.IUserService
|
||||||
|
import io.ktor.http.*
|
||||||
|
import org.koin.core.annotation.Single
|
||||||
|
|
||||||
|
@Single
|
||||||
|
class ActivityPubUndoServiceImpl(
|
||||||
|
private val userService: IUserService,
|
||||||
|
private val activityPubUserService: ActivityPubUserService
|
||||||
|
) : ActivityPubUndoService {
|
||||||
|
override suspend fun receiveUndo(undo: Undo): ActivityPubResponse {
|
||||||
|
|
||||||
|
if (undo.actor == null) {
|
||||||
|
return ActivityPubStringResponse(HttpStatusCode.BadRequest, "actor is null")
|
||||||
|
}
|
||||||
|
|
||||||
|
val type =
|
||||||
|
undo.`object`?.type.orEmpty()
|
||||||
|
.firstOrNull { it == "Block" || it == "Follow" || it == "Like" || it == "Announce" || it == "Accept" }
|
||||||
|
?: return ActivityPubStringResponse(HttpStatusCode.BadRequest, "unknown type ${undo.`object`?.type}")
|
||||||
|
|
||||||
|
when (type) {
|
||||||
|
"Follow" -> {
|
||||||
|
val follow = undo.`object` as Follow
|
||||||
|
|
||||||
|
if (follow.`object` == null) {
|
||||||
|
return ActivityPubStringResponse(HttpStatusCode.BadRequest, "object.object is null")
|
||||||
|
}
|
||||||
|
|
||||||
|
activityPubUserService.fetchPerson(undo.actor!!, follow.`object`)
|
||||||
|
val follower = userService.findByUrl(undo.actor!!)
|
||||||
|
val target = userService.findByUrl(follow.`object`!!)
|
||||||
|
userService.unfollow(target.id, follower.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,5 +5,12 @@ import dev.usbharu.hideout.domain.model.ap.Person
|
||||||
interface ActivityPubUserService {
|
interface ActivityPubUserService {
|
||||||
suspend fun getPersonByName(name: String): Person
|
suspend fun getPersonByName(name: String): Person
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch person
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @param targetActor 署名するユーザー
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
suspend fun fetchPerson(url: String, targetActor: String? = null): Person
|
suspend fun fetchPerson(url: String, targetActor: String? = null): Person
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,5 +45,7 @@ interface IUserService {
|
||||||
* @param follower
|
* @param follower
|
||||||
* @return リクエストが成功したか
|
* @return リクエストが成功したか
|
||||||
*/
|
*/
|
||||||
suspend fun addFollowers(id: Long, follower: Long): Boolean
|
suspend fun follow(id: Long, follower: Long): Boolean
|
||||||
|
|
||||||
|
suspend fun unfollow(id: Long, follower: Long): Boolean
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,8 +105,13 @@ class UserService(private val userRepository: IUserRepository, private val userA
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO APのフォロー処理を作る
|
// TODO APのフォロー処理を作る
|
||||||
override suspend fun addFollowers(id: Long, follower: Long): Boolean {
|
override suspend fun follow(id: Long, follower: Long): Boolean {
|
||||||
userRepository.createFollower(id, follower)
|
userRepository.createFollower(id, follower)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun unfollow(id: Long, follower: Long): Boolean {
|
||||||
|
userRepository.deleteFollower(id, follower)
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package dev.usbharu.hideout.domain.model.ap
|
||||||
|
|
||||||
|
import org.intellij.lang.annotations.Language
|
||||||
|
import org.junit.jupiter.api.Assertions.*
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import utils.JsonObjectMapper
|
||||||
|
import java.time.Clock
|
||||||
|
import java.time.Instant
|
||||||
|
import java.time.ZoneId
|
||||||
|
|
||||||
|
class UndoTest {
|
||||||
|
@Test
|
||||||
|
fun Undoのシリアライズができる() {
|
||||||
|
val undo = Undo(
|
||||||
|
emptyList(),
|
||||||
|
"Undo Follow",
|
||||||
|
"https://follower.example.com/",
|
||||||
|
"https://follower.example.com/undo/1",
|
||||||
|
Follow(
|
||||||
|
emptyList(),
|
||||||
|
null,
|
||||||
|
"https://follower.example.com/users/",
|
||||||
|
actor = "https://follower.exaple.com/users/1"
|
||||||
|
),
|
||||||
|
Instant.now(Clock.tickMillis(ZoneId.systemDefault()))
|
||||||
|
)
|
||||||
|
val writeValueAsString = JsonObjectMapper.objectMapper.writeValueAsString(undo)
|
||||||
|
println(writeValueAsString)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun Undoをデシリアライズ出来る() {
|
||||||
|
@Language("JSON") val json = """
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://w3id.org/security/v1",
|
||||||
|
{
|
||||||
|
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||||
|
"sensitive": "as:sensitive",
|
||||||
|
"Hashtag": "as:Hashtag",
|
||||||
|
"quoteUrl": "as:quoteUrl",
|
||||||
|
"toot": "http://joinmastodon.org/ns#",
|
||||||
|
"Emoji": "toot:Emoji",
|
||||||
|
"featured": "toot:featured",
|
||||||
|
"discoverable": "toot:discoverable",
|
||||||
|
"schema": "http://schema.org#",
|
||||||
|
"PropertyValue": "schema:PropertyValue",
|
||||||
|
"value": "schema:value",
|
||||||
|
"misskey": "https://misskey-hub.net/ns#",
|
||||||
|
"_misskey_content": "misskey:_misskey_content",
|
||||||
|
"_misskey_quote": "misskey:_misskey_quote",
|
||||||
|
"_misskey_reaction": "misskey:_misskey_reaction",
|
||||||
|
"_misskey_votes": "misskey:_misskey_votes",
|
||||||
|
"isCat": "misskey:isCat",
|
||||||
|
"vcard": "http://www.w3.org/2006/vcard/ns#"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "Undo",
|
||||||
|
"id": "https://misskey.usbharu.dev/follows/97ws8y3rj6/9ezbh8qrh0/undo",
|
||||||
|
"actor": "https://misskey.usbharu.dev/users/97ws8y3rj6",
|
||||||
|
"object": {
|
||||||
|
"id": "https://misskey.usbharu.dev/follows/97ws8y3rj6/9ezbh8qrh0",
|
||||||
|
"type": "Follow",
|
||||||
|
"actor": "https://misskey.usbharu.dev/users/97ws8y3rj6",
|
||||||
|
"object": "https://test-hideout.usbharu.dev/users/test"
|
||||||
|
},
|
||||||
|
"published": "2023-05-20T10:28:17.308Z"
|
||||||
|
}
|
||||||
|
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
val undo = JsonObjectMapper.objectMapper.readValue(json, Undo::class.java)
|
||||||
|
println(undo)
|
||||||
|
}
|
||||||
|
}
|
|
@ -432,7 +432,7 @@ class UsersTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val userService = mock<IUserService> {
|
val userService = mock<IUserService> {
|
||||||
onBlocking { addFollowers(eq(1235), eq(1234)) } doReturn true
|
onBlocking { follow(eq(1235), eq(1234)) } doReturn true
|
||||||
}
|
}
|
||||||
application {
|
application {
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
|
@ -482,7 +482,7 @@ class UsersTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val userService = mock<IUserService> {
|
val userService = mock<IUserService> {
|
||||||
onBlocking { addFollowers(eq(1235), eq(1234)) } doReturn false
|
onBlocking { follow(eq(1235), eq(1234)) } doReturn false
|
||||||
}
|
}
|
||||||
application {
|
application {
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
|
@ -532,7 +532,7 @@ class UsersTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val userService = mock<IUserService> {
|
val userService = mock<IUserService> {
|
||||||
onBlocking { addFollowers(eq(1235), eq(1234)) } doReturn false
|
onBlocking { follow(eq(1235), eq(1234)) } doReturn false
|
||||||
}
|
}
|
||||||
application {
|
application {
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
|
|
|
@ -115,7 +115,7 @@ class ActivityPubFollowServiceImplTest {
|
||||||
createdAt = Instant.now()
|
createdAt = Instant.now()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
onBlocking { addFollowers(any(), any()) } doReturn false
|
onBlocking { follow(any(), any()) } doReturn false
|
||||||
}
|
}
|
||||||
val activityPubFollowService =
|
val activityPubFollowService =
|
||||||
ActivityPubFollowServiceImpl(
|
ActivityPubFollowServiceImpl(
|
||||||
|
@ -137,10 +137,12 @@ class ActivityPubFollowServiceImplTest {
|
||||||
actor = "https://example.com"
|
actor = "https://example.com"
|
||||||
)
|
)
|
||||||
accept.context += "https://www.w3.org/ns/activitystreams"
|
accept.context += "https://www.w3.org/ns/activitystreams"
|
||||||
|
val content = httpRequestData.body.toByteArray().decodeToString()
|
||||||
|
println(content)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
accept,
|
accept,
|
||||||
Config.configData.objectMapper.readValue<Accept>(
|
Config.configData.objectMapper.readValue<Accept>(
|
||||||
httpRequestData.body.toByteArray().decodeToString()
|
content
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
respondOk()
|
respondOk()
|
||||||
|
|
Loading…
Reference in New Issue