mirror of https://github.com/usbharu/Hideout.git
Merge pull request #26 from usbharu/feature/deliver-reaction
Feature/deliver reaction
This commit is contained in:
commit
2a6edd7da9
|
@ -59,7 +59,7 @@ kotlin {
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets.main {
|
sourceSets.main {
|
||||||
java.srcDirs("build/generated/ksp/main/kotlin")
|
kotlin.srcDirs("$buildDir/generated/ksp/main")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,7 +14,7 @@
|
||||||
"@suid/vite-plugin": "^0.1.3",
|
"@suid/vite-plugin": "^0.1.3",
|
||||||
"rollup-plugin-visualizer": "^5.9.2",
|
"rollup-plugin-visualizer": "^5.9.2",
|
||||||
"typescript": "^5.0.4",
|
"typescript": "^5.0.4",
|
||||||
"vite": "^4.2.1",
|
"vite": "4.2.3",
|
||||||
"vite-plugin-solid": "^2.7.0"
|
"vite-plugin-solid": "^2.7.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -8,6 +8,8 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import dev.usbharu.hideout.config.Config
|
import dev.usbharu.hideout.config.Config
|
||||||
import dev.usbharu.hideout.config.ConfigData
|
import dev.usbharu.hideout.config.ConfigData
|
||||||
import dev.usbharu.hideout.domain.model.job.DeliverPostJob
|
import dev.usbharu.hideout.domain.model.job.DeliverPostJob
|
||||||
|
import dev.usbharu.hideout.domain.model.job.DeliverReactionJob
|
||||||
|
import dev.usbharu.hideout.domain.model.job.DeliverRemoveReactionJob
|
||||||
import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob
|
import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob
|
||||||
import dev.usbharu.hideout.plugins.*
|
import dev.usbharu.hideout.plugins.*
|
||||||
import dev.usbharu.hideout.repository.IUserRepository
|
import dev.usbharu.hideout.repository.IUserRepository
|
||||||
|
@ -24,6 +26,7 @@ import dev.usbharu.hideout.service.core.IdGenerateService
|
||||||
import dev.usbharu.hideout.service.core.TwitterSnowflakeIdGenerateService
|
import dev.usbharu.hideout.service.core.TwitterSnowflakeIdGenerateService
|
||||||
import dev.usbharu.hideout.service.job.JobQueueParentService
|
import dev.usbharu.hideout.service.job.JobQueueParentService
|
||||||
import dev.usbharu.hideout.service.job.KJobJobQueueParentService
|
import dev.usbharu.hideout.service.job.KJobJobQueueParentService
|
||||||
|
import dev.usbharu.hideout.service.reaction.IReactionService
|
||||||
import dev.usbharu.hideout.service.user.IUserAuthService
|
import dev.usbharu.hideout.service.user.IUserAuthService
|
||||||
import dev.usbharu.hideout.service.user.IUserService
|
import dev.usbharu.hideout.service.user.IUserService
|
||||||
import dev.usbharu.kjob.exposed.ExposedKJob
|
import dev.usbharu.kjob.exposed.ExposedKJob
|
||||||
|
@ -102,6 +105,7 @@ fun Application.parent() {
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
register(inject<IUserService>().value)
|
register(inject<IUserService>().value)
|
||||||
configureSecurity(
|
configureSecurity(
|
||||||
|
|
||||||
inject<JwkProvider>().value,
|
inject<JwkProvider>().value,
|
||||||
inject<IMetaService>().value
|
inject<IMetaService>().value
|
||||||
)
|
)
|
||||||
|
@ -112,6 +116,7 @@ fun Application.parent() {
|
||||||
activityPubUserService = inject<ActivityPubUserService>().value,
|
activityPubUserService = inject<ActivityPubUserService>().value,
|
||||||
postService = inject<IPostApiService>().value,
|
postService = inject<IPostApiService>().value,
|
||||||
userApiService = inject<IUserApiService>().value,
|
userApiService = inject<IUserApiService>().value,
|
||||||
|
reactionService = inject<IReactionService>().value,
|
||||||
userAuthService = inject<IUserAuthService>().value,
|
userAuthService = inject<IUserAuthService>().value,
|
||||||
userRepository = inject<IUserRepository>().value,
|
userRepository = inject<IUserRepository>().value,
|
||||||
jwtService = inject<IJwtService>().value,
|
jwtService = inject<IJwtService>().value,
|
||||||
|
@ -137,4 +142,16 @@ fun Application.worker() {
|
||||||
activityPubService.processActivity(this, it)
|
activityPubService.processActivity(this, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kJob.register(DeliverReactionJob) {
|
||||||
|
execute {
|
||||||
|
activityPubService.processActivity(this, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kJob.register(DeliverRemoveReactionJob) {
|
||||||
|
execute {
|
||||||
|
activityPubService.processActivity(this, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,13 @@ open class Like : Object {
|
||||||
|
|
||||||
protected constructor() : super()
|
protected constructor() : super()
|
||||||
constructor(
|
constructor(
|
||||||
type: List<String>,
|
type: List<String> = emptyList(),
|
||||||
name: String?,
|
name: String?,
|
||||||
actor: String?,
|
actor: String?,
|
||||||
id: String?,
|
id: String?,
|
||||||
`object`: String?,
|
`object`: String?,
|
||||||
content: String?,
|
content: String?,
|
||||||
tag: List<Object>
|
tag: List<Object> = emptyList()
|
||||||
) : super(
|
) : super(
|
||||||
type = add(type, "Like"),
|
type = add(type, "Like"),
|
||||||
name = name,
|
name = name,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import com.fasterxml.jackson.databind.JsonNode
|
||||||
import dev.usbharu.hideout.service.activitypub.ExtendedActivityVocabulary
|
import dev.usbharu.hideout.service.activitypub.ExtendedActivityVocabulary
|
||||||
|
|
||||||
class ObjectDeserializer : JsonDeserializer<Object>() {
|
class ObjectDeserializer : JsonDeserializer<Object>() {
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||||
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Object {
|
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Object {
|
||||||
requireNotNull(p)
|
requireNotNull(p)
|
||||||
val treeNode: JsonNode = requireNotNull(p.codec?.readTree(p))
|
val treeNode: JsonNode = requireNotNull(p.codec?.readTree(p))
|
||||||
|
|
|
@ -5,7 +5,7 @@ import dev.usbharu.hideout.domain.model.hideout.entity.User
|
||||||
import dev.usbharu.hideout.domain.model.hideout.entity.Visibility
|
import dev.usbharu.hideout.domain.model.hideout.entity.Visibility
|
||||||
|
|
||||||
data class PostResponse(
|
data class PostResponse(
|
||||||
val id: Long,
|
val id: String,
|
||||||
val user: UserResponse,
|
val user: UserResponse,
|
||||||
val overview: String? = null,
|
val overview: String? = null,
|
||||||
val text: String? = null,
|
val text: String? = null,
|
||||||
|
@ -17,7 +17,7 @@ data class PostResponse(
|
||||||
companion object {
|
companion object {
|
||||||
fun from(post: Post, user: User): PostResponse {
|
fun from(post: Post, user: User): PostResponse {
|
||||||
return PostResponse(
|
return PostResponse(
|
||||||
id = post.id,
|
id = post.id.toString(),
|
||||||
user = UserResponse.from(user),
|
user = UserResponse.from(user),
|
||||||
overview = post.overview,
|
overview = post.overview,
|
||||||
text = post.text,
|
text = post.text,
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package dev.usbharu.hideout.domain.model.hideout.dto
|
||||||
|
|
||||||
|
data class ReactionResponse(
|
||||||
|
val reaction: String,
|
||||||
|
val isUnicodeEmoji: Boolean = true,
|
||||||
|
val iconUrl: String,
|
||||||
|
val accounts: List<Account>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Account(val screenName: String, val iconUrl: String, val url: String)
|
|
@ -3,7 +3,7 @@ package dev.usbharu.hideout.domain.model.hideout.dto
|
||||||
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
||||||
|
|
||||||
data class UserResponse(
|
data class UserResponse(
|
||||||
val id: Long,
|
val id: String,
|
||||||
val name: String,
|
val name: String,
|
||||||
val domain: String,
|
val domain: String,
|
||||||
val screenName: String,
|
val screenName: String,
|
||||||
|
@ -14,7 +14,7 @@ data class UserResponse(
|
||||||
companion object {
|
companion object {
|
||||||
fun from(user: User): UserResponse {
|
fun from(user: User): UserResponse {
|
||||||
return UserResponse(
|
return UserResponse(
|
||||||
id = user.id,
|
id = user.id.toString(),
|
||||||
name = user.name,
|
name = user.name,
|
||||||
domain = user.domain,
|
domain = user.domain,
|
||||||
screenName = user.screenName,
|
screenName = user.screenName,
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package dev.usbharu.hideout.domain.model.hideout.form
|
||||||
|
|
||||||
|
data class Reaction(val reaction: String?)
|
|
@ -15,3 +15,18 @@ object DeliverPostJob : HideoutJob("DeliverPostJob") {
|
||||||
val actor = string("actor")
|
val actor = string("actor")
|
||||||
val inbox = string("inbox")
|
val inbox = string("inbox")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object DeliverReactionJob : HideoutJob("DeliverReactionJob") {
|
||||||
|
val reaction = string("reaction")
|
||||||
|
val postUrl = string("postUrl")
|
||||||
|
val actor = string("actor")
|
||||||
|
val inbox = string("inbox")
|
||||||
|
val id = string("id")
|
||||||
|
}
|
||||||
|
|
||||||
|
object DeliverRemoveReactionJob : HideoutJob("DeliverRemoveReactionJob") {
|
||||||
|
val id = string("id")
|
||||||
|
val inbox = string("inbox")
|
||||||
|
val actor = string("actor")
|
||||||
|
val like = string("like")
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import dev.usbharu.hideout.service.api.IUserApiService
|
||||||
import dev.usbharu.hideout.service.auth.HttpSignatureVerifyService
|
import dev.usbharu.hideout.service.auth.HttpSignatureVerifyService
|
||||||
import dev.usbharu.hideout.service.auth.IJwtService
|
import dev.usbharu.hideout.service.auth.IJwtService
|
||||||
import dev.usbharu.hideout.service.core.IMetaService
|
import dev.usbharu.hideout.service.core.IMetaService
|
||||||
|
import dev.usbharu.hideout.service.reaction.IReactionService
|
||||||
import dev.usbharu.hideout.service.user.IUserAuthService
|
import dev.usbharu.hideout.service.user.IUserAuthService
|
||||||
import dev.usbharu.hideout.service.user.IUserService
|
import dev.usbharu.hideout.service.user.IUserService
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
|
@ -29,6 +30,7 @@ fun Application.configureRouting(
|
||||||
activityPubUserService: ActivityPubUserService,
|
activityPubUserService: ActivityPubUserService,
|
||||||
postService: IPostApiService,
|
postService: IPostApiService,
|
||||||
userApiService: IUserApiService,
|
userApiService: IUserApiService,
|
||||||
|
reactionService: IReactionService,
|
||||||
userAuthService: IUserAuthService,
|
userAuthService: IUserAuthService,
|
||||||
userRepository: IUserRepository,
|
userRepository: IUserRepository,
|
||||||
jwtService: IJwtService,
|
jwtService: IJwtService,
|
||||||
|
@ -41,7 +43,7 @@ fun Application.configureRouting(
|
||||||
usersAP(activityPubUserService, userService)
|
usersAP(activityPubUserService, userService)
|
||||||
webfinger(userService)
|
webfinger(userService)
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, reactionService)
|
||||||
users(userService, userApiService)
|
users(userService, userApiService)
|
||||||
auth(userAuthService, userRepository, jwtService)
|
auth(userAuthService, userRepository, jwtService)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,4 +6,10 @@ interface ReactionRepository {
|
||||||
suspend fun generateId(): Long
|
suspend fun generateId(): Long
|
||||||
suspend fun save(reaction: Reaction): Reaction
|
suspend fun save(reaction: Reaction): Reaction
|
||||||
suspend fun reactionAlreadyExist(postId: Long, userId: Long, emojiId: Long): Boolean
|
suspend fun reactionAlreadyExist(postId: Long, userId: Long, emojiId: Long): Boolean
|
||||||
|
suspend fun findByPostId(postId: Long): List<Reaction>
|
||||||
|
suspend fun delete(reaction: Reaction): Reaction
|
||||||
|
suspend fun deleteById(id: Long)
|
||||||
|
suspend fun deleteByPostId(postId: Long)
|
||||||
|
suspend fun deleteByUserId(userId: Long)
|
||||||
|
suspend fun deleteByPostIdAndUserId(postId: Long, userId: Long)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import dev.usbharu.hideout.service.core.IdGenerateService
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import org.jetbrains.exposed.dao.id.LongIdTable
|
import org.jetbrains.exposed.dao.id.LongIdTable
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
|
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.koin.core.annotation.Single
|
import org.koin.core.annotation.Single
|
||||||
|
@ -57,6 +58,50 @@ class ReactionRepositoryImpl(
|
||||||
}.empty().not()
|
}.empty().not()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun findByPostId(postId: Long): List<Reaction> {
|
||||||
|
return query {
|
||||||
|
Reactions.select {
|
||||||
|
Reactions.postId.eq(postId)
|
||||||
|
}.map { it.toReaction() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun delete(reaction: Reaction): Reaction {
|
||||||
|
query {
|
||||||
|
Reactions.deleteWhere {
|
||||||
|
id.eq(reaction.id)
|
||||||
|
.and(postId.eq(reaction.postId))
|
||||||
|
.and(userId.eq(reaction.postId))
|
||||||
|
.and(emojiId.eq(reaction.emojiId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return reaction
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteById(id: Long) {
|
||||||
|
query {
|
||||||
|
Reactions.deleteWhere { Reactions.id.eq(id) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteByPostId(postId: Long) {
|
||||||
|
query {
|
||||||
|
Reactions.deleteWhere { Reactions.postId.eq(postId) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteByUserId(userId: Long) {
|
||||||
|
query {
|
||||||
|
Reactions.deleteWhere { Reactions.userId.eq(userId) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteByPostIdAndUserId(postId: Long, userId: Long) {
|
||||||
|
query {
|
||||||
|
Reactions.deleteWhere { Reactions.postId.eq(postId).and(Reactions.userId.eq(userId)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ResultRow.toReaction(): Reaction {
|
fun ResultRow.toReaction(): Reaction {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package dev.usbharu.hideout.routing.api.internal.v1
|
package dev.usbharu.hideout.routing.api.internal.v1
|
||||||
|
|
||||||
import dev.usbharu.hideout.domain.model.hideout.form.Post
|
import dev.usbharu.hideout.domain.model.hideout.form.Post
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.form.Reaction
|
||||||
import dev.usbharu.hideout.exception.ParameterNotExistException
|
import dev.usbharu.hideout.exception.ParameterNotExistException
|
||||||
import dev.usbharu.hideout.plugins.TOKEN_AUTH
|
import dev.usbharu.hideout.plugins.TOKEN_AUTH
|
||||||
import dev.usbharu.hideout.service.api.IPostApiService
|
import dev.usbharu.hideout.service.api.IPostApiService
|
||||||
|
import dev.usbharu.hideout.service.reaction.IReactionService
|
||||||
import dev.usbharu.hideout.util.InstantParseUtil
|
import dev.usbharu.hideout.util.InstantParseUtil
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
|
@ -14,7 +16,7 @@ import io.ktor.server.response.*
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
|
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
fun Route.posts(postApiService: IPostApiService) {
|
fun Route.posts(postApiService: IPostApiService, reactionService: IReactionService) {
|
||||||
route("/posts") {
|
route("/posts") {
|
||||||
authenticate(TOKEN_AUTH) {
|
authenticate(TOKEN_AUTH) {
|
||||||
post {
|
post {
|
||||||
|
@ -26,6 +28,39 @@ fun Route.posts(postApiService: IPostApiService) {
|
||||||
call.response.header("Location", create.url)
|
call.response.header("Location", create.url)
|
||||||
call.respond(HttpStatusCode.OK)
|
call.respond(HttpStatusCode.OK)
|
||||||
}
|
}
|
||||||
|
route("/{id}/reactions") {
|
||||||
|
get {
|
||||||
|
val principal = call.principal<JWTPrincipal>() ?: throw IllegalStateException("no principal")
|
||||||
|
val userId = principal.payload.getClaim("uid").asLong()
|
||||||
|
val postId = (
|
||||||
|
call.parameters["id"]?.toLong()
|
||||||
|
?: throw ParameterNotExistException("Parameter(id='postsId') does not exist.")
|
||||||
|
)
|
||||||
|
call.respond(reactionService.findByPostIdForUser(postId, userId))
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
val jwtPrincipal = call.principal<JWTPrincipal>() ?: throw IllegalStateException("no principal")
|
||||||
|
val userId = jwtPrincipal.payload.getClaim("uid").asLong()
|
||||||
|
val postId = call.parameters["id"]?.toLong()
|
||||||
|
?: throw ParameterNotExistException("Parameter(id='postsId') does not exist.")
|
||||||
|
val reaction = try {
|
||||||
|
call.receive<Reaction>()
|
||||||
|
} catch (e: ContentTransformationException) {
|
||||||
|
Reaction(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
reactionService.sendReaction(reaction.reaction ?: "❤", userId, postId)
|
||||||
|
call.respond(HttpStatusCode.NoContent)
|
||||||
|
}
|
||||||
|
delete {
|
||||||
|
val jwtPrincipal = call.principal<JWTPrincipal>() ?: throw IllegalStateException("no principal")
|
||||||
|
val userId = jwtPrincipal.payload.getClaim("uid").asLong()
|
||||||
|
val postId = call.parameters["id"]?.toLong()
|
||||||
|
?: throw ParameterNotExistException("Parameter(id='postsId') does not exist.")
|
||||||
|
reactionService.removeReaction(userId, postId)
|
||||||
|
call.respond(HttpStatusCode.NoContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
authenticate(TOKEN_AUTH, optional = true) {
|
authenticate(TOKEN_AUTH, optional = true) {
|
||||||
get {
|
get {
|
||||||
|
|
|
@ -81,7 +81,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.followRequest(targetUser.id, userId)) {
|
if (userService.followRequest(targetUser.id.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)
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package dev.usbharu.hideout.service.activitypub
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.Reaction
|
||||||
|
import dev.usbharu.hideout.domain.model.job.DeliverReactionJob
|
||||||
|
import dev.usbharu.hideout.domain.model.job.DeliverRemoveReactionJob
|
||||||
|
import kjob.core.job.JobProps
|
||||||
|
|
||||||
|
interface ActivityPubReactionService {
|
||||||
|
suspend fun reaction(like: Reaction)
|
||||||
|
suspend fun removeReaction(like: Reaction)
|
||||||
|
suspend fun reactionJob(props: JobProps<DeliverReactionJob>)
|
||||||
|
suspend fun removeReactionJob(props: JobProps<DeliverRemoveReactionJob>)
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
package dev.usbharu.hideout.service.activitypub
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
|
import dev.usbharu.hideout.config.Config
|
||||||
|
import dev.usbharu.hideout.domain.model.ap.Like
|
||||||
|
import dev.usbharu.hideout.domain.model.ap.Undo
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.Reaction
|
||||||
|
import dev.usbharu.hideout.domain.model.job.DeliverReactionJob
|
||||||
|
import dev.usbharu.hideout.domain.model.job.DeliverRemoveReactionJob
|
||||||
|
import dev.usbharu.hideout.exception.PostNotFoundException
|
||||||
|
import dev.usbharu.hideout.plugins.postAp
|
||||||
|
import dev.usbharu.hideout.repository.IPostRepository
|
||||||
|
import dev.usbharu.hideout.service.job.JobQueueParentService
|
||||||
|
import dev.usbharu.hideout.service.user.IUserService
|
||||||
|
import io.ktor.client.*
|
||||||
|
import kjob.core.job.JobProps
|
||||||
|
import org.koin.core.annotation.Single
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
@Single
|
||||||
|
class ActivityPubReactionServiceImpl(
|
||||||
|
private val userService: IUserService,
|
||||||
|
private val jobQueueParentService: JobQueueParentService,
|
||||||
|
private val iPostRepository: IPostRepository,
|
||||||
|
private val httpClient: HttpClient
|
||||||
|
) : ActivityPubReactionService {
|
||||||
|
override suspend fun reaction(like: Reaction) {
|
||||||
|
val followers = userService.findFollowersById(like.userId)
|
||||||
|
val user = userService.findById(like.userId)
|
||||||
|
val post =
|
||||||
|
iPostRepository.findOneById(like.postId) ?: throw PostNotFoundException("${like.postId} was not found.")
|
||||||
|
followers.forEach { follower ->
|
||||||
|
jobQueueParentService.schedule(DeliverReactionJob) {
|
||||||
|
props[it.actor] = user.url
|
||||||
|
props[it.reaction] = "❤"
|
||||||
|
props[it.inbox] = follower.inbox
|
||||||
|
props[it.postUrl] = post.url
|
||||||
|
props[it.id] = post.id.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun removeReaction(like: Reaction) {
|
||||||
|
val followers = userService.findFollowersById(like.userId)
|
||||||
|
val user = userService.findById(like.userId)
|
||||||
|
val post =
|
||||||
|
iPostRepository.findOneById(like.postId) ?: throw PostNotFoundException("${like.postId} was not found.")
|
||||||
|
followers.forEach { follower ->
|
||||||
|
jobQueueParentService.schedule(DeliverRemoveReactionJob) {
|
||||||
|
props[it.actor] = user.url
|
||||||
|
props[it.inbox] = follower.inbox
|
||||||
|
props[it.id] = post.id.toString()
|
||||||
|
props[it.like] = Config.configData.objectMapper.writeValueAsString(like)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun reactionJob(props: JobProps<DeliverReactionJob>) {
|
||||||
|
val inbox = props[DeliverReactionJob.inbox]
|
||||||
|
val actor = props[DeliverReactionJob.actor]
|
||||||
|
val postUrl = props[DeliverReactionJob.postUrl]
|
||||||
|
val id = props[DeliverReactionJob.id]
|
||||||
|
val content = props[DeliverReactionJob.reaction]
|
||||||
|
httpClient.postAp(
|
||||||
|
urlString = inbox,
|
||||||
|
username = "$actor#pubkey",
|
||||||
|
jsonLd = Like(
|
||||||
|
name = "Like",
|
||||||
|
actor = actor,
|
||||||
|
`object` = postUrl,
|
||||||
|
id = "${Config.configData.url}/like/note/$id",
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun removeReactionJob(props: JobProps<DeliverRemoveReactionJob>) {
|
||||||
|
val inbox = props[DeliverRemoveReactionJob.inbox]
|
||||||
|
val actor = props[DeliverRemoveReactionJob.actor]
|
||||||
|
val like = Config.configData.objectMapper.readValue<Like>(props[DeliverRemoveReactionJob.like])
|
||||||
|
httpClient.postAp(
|
||||||
|
urlString = inbox,
|
||||||
|
username = "$actor#pubkey",
|
||||||
|
jsonLd = Undo(
|
||||||
|
name = "Undo Reaction",
|
||||||
|
actor = actor,
|
||||||
|
`object` = like,
|
||||||
|
id = "${Config.configData.url}/undo/note/${like.id}",
|
||||||
|
published = Instant.now()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,9 +5,7 @@ import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import dev.usbharu.hideout.config.Config.configData
|
import dev.usbharu.hideout.config.Config.configData
|
||||||
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
|
||||||
import dev.usbharu.hideout.domain.model.job.DeliverPostJob
|
import dev.usbharu.hideout.domain.model.job.*
|
||||||
import dev.usbharu.hideout.domain.model.job.HideoutJob
|
|
||||||
import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob
|
|
||||||
import dev.usbharu.hideout.exception.JsonParseException
|
import dev.usbharu.hideout.exception.JsonParseException
|
||||||
import kjob.core.dsl.JobContextWithProps
|
import kjob.core.dsl.JobContextWithProps
|
||||||
import kjob.core.job.JobProps
|
import kjob.core.job.JobProps
|
||||||
|
@ -22,7 +20,8 @@ class ActivityPubServiceImpl(
|
||||||
private val activityPubUndoService: ActivityPubUndoService,
|
private val activityPubUndoService: ActivityPubUndoService,
|
||||||
private val activityPubAcceptService: ActivityPubAcceptService,
|
private val activityPubAcceptService: ActivityPubAcceptService,
|
||||||
private val activityPubCreateService: ActivityPubCreateService,
|
private val activityPubCreateService: ActivityPubCreateService,
|
||||||
private val activityPubLikeService: ActivityPubLikeService
|
private val activityPubLikeService: ActivityPubLikeService,
|
||||||
|
private val activityPubReactionService: ActivityPubReactionService
|
||||||
) : ActivityPubService {
|
) : ActivityPubService {
|
||||||
|
|
||||||
val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
||||||
|
@ -71,6 +70,10 @@ class ActivityPubServiceImpl(
|
||||||
)
|
)
|
||||||
|
|
||||||
DeliverPostJob -> activityPubNoteService.createNoteJob(job.props as JobProps<DeliverPostJob>)
|
DeliverPostJob -> activityPubNoteService.createNoteJob(job.props as JobProps<DeliverPostJob>)
|
||||||
|
DeliverReactionJob -> activityPubReactionService.reactionJob(job.props as JobProps<DeliverReactionJob>)
|
||||||
|
DeliverRemoveReactionJob -> activityPubReactionService.removeReactionJob(
|
||||||
|
job.props as JobProps<DeliverRemoveReactionJob>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
package dev.usbharu.hideout.service.reaction
|
package dev.usbharu.hideout.service.reaction
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.dto.ReactionResponse
|
||||||
|
|
||||||
interface IReactionService {
|
interface IReactionService {
|
||||||
suspend fun receiveReaction(name: String, domain: String, userId: Long, postId: Long)
|
suspend fun receiveReaction(name: String, domain: String, userId: Long, postId: Long)
|
||||||
|
suspend fun sendReaction(name: String, userId: Long, postId: Long)
|
||||||
|
suspend fun removeReaction(userId: Long, postId: Long)
|
||||||
|
suspend fun findByPostIdForUser(postId: Long, userId: Long): List<ReactionResponse>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,23 @@
|
||||||
package dev.usbharu.hideout.service.reaction
|
package dev.usbharu.hideout.service.reaction
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.dto.Account
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.dto.ReactionResponse
|
||||||
import dev.usbharu.hideout.domain.model.hideout.entity.Reaction
|
import dev.usbharu.hideout.domain.model.hideout.entity.Reaction
|
||||||
import dev.usbharu.hideout.repository.ReactionRepository
|
import dev.usbharu.hideout.repository.ReactionRepository
|
||||||
|
import dev.usbharu.hideout.repository.Reactions
|
||||||
|
import dev.usbharu.hideout.repository.Users
|
||||||
|
import dev.usbharu.hideout.service.activitypub.ActivityPubReactionService
|
||||||
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
|
import org.jetbrains.exposed.sql.leftJoin
|
||||||
|
import org.jetbrains.exposed.sql.select
|
||||||
|
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
|
||||||
import org.koin.core.annotation.Single
|
import org.koin.core.annotation.Single
|
||||||
|
|
||||||
@Single
|
@Single
|
||||||
class ReactionServiceImpl(private val reactionRepository: ReactionRepository) : IReactionService {
|
class ReactionServiceImpl(
|
||||||
|
private val reactionRepository: ReactionRepository,
|
||||||
|
private val activityPubReactionService: ActivityPubReactionService
|
||||||
|
) : IReactionService {
|
||||||
override suspend fun receiveReaction(name: String, domain: String, userId: Long, postId: Long) {
|
override suspend fun receiveReaction(name: String, domain: String, userId: Long, postId: Long) {
|
||||||
if (reactionRepository.reactionAlreadyExist(postId, userId, 0).not()) {
|
if (reactionRepository.reactionAlreadyExist(postId, userId, 0).not()) {
|
||||||
reactionRepository.save(
|
reactionRepository.save(
|
||||||
|
@ -13,4 +25,31 @@ class ReactionServiceImpl(private val reactionRepository: ReactionRepository) :
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun sendReaction(name: String, userId: Long, postId: Long) {
|
||||||
|
if (reactionRepository.reactionAlreadyExist(postId, userId, 0)) {
|
||||||
|
// delete
|
||||||
|
reactionRepository.deleteByPostIdAndUserId(postId, userId)
|
||||||
|
} else {
|
||||||
|
val reaction = Reaction(reactionRepository.generateId(), 0, postId, userId)
|
||||||
|
reactionRepository.save(reaction)
|
||||||
|
activityPubReactionService.reaction(reaction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun removeReaction(userId: Long, postId: Long) {
|
||||||
|
reactionRepository.deleteByPostIdAndUserId(postId, userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun findByPostIdForUser(postId: Long, userId: Long): List<ReactionResponse> {
|
||||||
|
return newSuspendedTransaction {
|
||||||
|
Reactions
|
||||||
|
.leftJoin(Users, onColumn = { Reactions.userId }, otherColumn = { id })
|
||||||
|
.select { Reactions.postId.eq(postId) }
|
||||||
|
.groupBy { resultRow: ResultRow -> ReactionResponse("❤", true, "", listOf()) }
|
||||||
|
.map { entry: Map.Entry<ReactionResponse, List<ResultRow>> ->
|
||||||
|
entry.key.copy(accounts = entry.value.map { Account(it[Users.screenName], "", it[Users.url]) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,71 @@ paths:
|
||||||
$ref: "#/components/responses/NotFoundOrForbidden"
|
$ref: "#/components/responses/NotFoundOrForbidden"
|
||||||
429:
|
429:
|
||||||
$ref: "#/components/responses/TooManyRequests"
|
$ref: "#/components/responses/TooManyRequests"
|
||||||
|
/posts/{postId}/reactions:
|
||||||
|
get:
|
||||||
|
summary: リアクションを数件返す
|
||||||
|
security:
|
||||||
|
- BearerAuth: [ ]
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/postId"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: 成功
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ReactionResponse"
|
||||||
|
401:
|
||||||
|
$ref: "#/components/responses/Unauthorized"
|
||||||
|
403:
|
||||||
|
$ref: "#/components/responses/Forbidden"
|
||||||
|
404:
|
||||||
|
$ref: "#/components/responses/NotFoundOrForbidden"
|
||||||
|
429:
|
||||||
|
$ref: "#/components/responses/TooManyRequests"
|
||||||
|
|
||||||
|
post:
|
||||||
|
summary: リアクションを付ける
|
||||||
|
security:
|
||||||
|
- BearerAuth: [ ]
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/postId"
|
||||||
|
requestBody:
|
||||||
|
description: 付けるリアクション
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Reaction"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: 成功
|
||||||
|
401:
|
||||||
|
$ref: "#/components/responses/Unauthorized"
|
||||||
|
403:
|
||||||
|
$ref: "#/components/responses/Forbidden"
|
||||||
|
404:
|
||||||
|
$ref: "#/components/responses/NotFoundOrForbidden"
|
||||||
|
429:
|
||||||
|
$ref: "#/components/responses/TooManyRequests"
|
||||||
|
delete:
|
||||||
|
summary: リアクションを削除する
|
||||||
|
security:
|
||||||
|
- BearerAuth: [ ]
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/postId"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: 成功
|
||||||
|
401:
|
||||||
|
$ref: "#/components/responses/Unauthorized"
|
||||||
|
403:
|
||||||
|
$ref: "#/components/responses/Forbidden"
|
||||||
|
404:
|
||||||
|
$ref: "#/components/responses/NotFoundOrForbidden"
|
||||||
|
429:
|
||||||
|
$ref: "#/components/responses/TooManyRequests"
|
||||||
|
|
||||||
/users/{userName}/posts:
|
/users/{userName}/posts:
|
||||||
get:
|
get:
|
||||||
summary: 権限に応じてユーザーの投稿一覧を返す
|
summary: 権限に応じてユーザーの投稿一覧を返す
|
||||||
|
@ -290,8 +355,7 @@ components:
|
||||||
description: 投稿ID
|
description: 投稿ID
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: integer
|
type: string
|
||||||
format: int64
|
|
||||||
userName:
|
userName:
|
||||||
name: userName
|
name: userName
|
||||||
in: path
|
in: path
|
||||||
|
@ -320,8 +384,7 @@ components:
|
||||||
- createdAt
|
- createdAt
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
type: number
|
type: string
|
||||||
format: int64
|
|
||||||
readOnly: true
|
readOnly: true
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
|
@ -337,7 +400,7 @@ components:
|
||||||
type: string
|
type: string
|
||||||
readOnly: true
|
readOnly: true
|
||||||
createdAt:
|
createdAt:
|
||||||
type: number
|
type: integer
|
||||||
readOnly: true
|
readOnly: true
|
||||||
PostResponse:
|
PostResponse:
|
||||||
type: object
|
type: object
|
||||||
|
@ -351,8 +414,7 @@ components:
|
||||||
- sensitive
|
- sensitive
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
type: integer
|
type: string
|
||||||
format: int64
|
|
||||||
readOnly: true
|
readOnly: true
|
||||||
user:
|
user:
|
||||||
$ref: "#/components/schemas/UserResponse"
|
$ref: "#/components/schemas/UserResponse"
|
||||||
|
@ -371,12 +433,10 @@ components:
|
||||||
format: uri
|
format: uri
|
||||||
readOnly: true
|
readOnly: true
|
||||||
repostId:
|
repostId:
|
||||||
type: integer
|
type: string
|
||||||
format: int64
|
|
||||||
readOnly: true
|
readOnly: true
|
||||||
replyId:
|
replyId:
|
||||||
type: integer
|
type: string
|
||||||
format: int64
|
|
||||||
readOnly: true
|
readOnly: true
|
||||||
sensitive:
|
sensitive:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
@ -391,11 +451,9 @@ components:
|
||||||
visibility:
|
visibility:
|
||||||
$ref: "#/components/schemas/Visibility"
|
$ref: "#/components/schemas/Visibility"
|
||||||
repostId:
|
repostId:
|
||||||
type: integer
|
type: string
|
||||||
format: int64
|
|
||||||
replyId:
|
replyId:
|
||||||
type: integer
|
type: string
|
||||||
format: int64
|
|
||||||
sensitive:
|
sensitive:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|
||||||
|
@ -421,6 +479,36 @@ components:
|
||||||
password:
|
password:
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
|
Reaction:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
reaction:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
ReactionResponse:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
reaction:
|
||||||
|
type: string
|
||||||
|
isUnicodeEmoji:
|
||||||
|
type: boolean
|
||||||
|
iconUrl:
|
||||||
|
type: string
|
||||||
|
accounts:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Account"
|
||||||
|
|
||||||
|
Account:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
screenName:
|
||||||
|
type: string
|
||||||
|
iconUrl:
|
||||||
|
type: string
|
||||||
|
url:
|
||||||
|
type: string
|
||||||
|
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
BearerAuth:
|
BearerAuth:
|
||||||
type: http
|
type: http
|
||||||
|
|
|
@ -4,14 +4,22 @@ import {Avatar} from "../atoms/Avatar";
|
||||||
import {Favorite, MoreVert, Reply, ScreenRotationAlt} from "@suid/icons-material";
|
import {Favorite, MoreVert, Reply, ScreenRotationAlt} from "@suid/icons-material";
|
||||||
import {ShareScopeIndicator} from "../molecules/ShareScopeIndicator";
|
import {ShareScopeIndicator} from "../molecules/ShareScopeIndicator";
|
||||||
import {PostResponse} from "../generated";
|
import {PostResponse} from "../generated";
|
||||||
|
import {useApi} from "../lib/ApiProvider";
|
||||||
|
|
||||||
export const Post: Component<{ post: PostResponse }> = (props) => {
|
export const Post: Component<{ post: PostResponse }> = (props) => {
|
||||||
|
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
const [anchorEl, setAnchorEl] = createSignal<null | HTMLElement>(null)
|
const [anchorEl, setAnchorEl] = createSignal<null | HTMLElement>(null)
|
||||||
const open = () => Boolean(anchorEl());
|
const open = () => Boolean(anchorEl());
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setAnchorEl(null);
|
setAnchorEl(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleFavorite = () => {
|
||||||
|
api().postsPostIdReactionsPost({reaction: "❤"}, props.post.id)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader avatar={<Avatar src={props.post.user.url + "/icon.jpg"}/>} title={props.post.user.screenName}
|
<CardHeader avatar={<Avatar src={props.post.user.url + "/icon.jpg"}/>} title={props.post.user.screenName}
|
||||||
|
@ -32,7 +40,7 @@ export const Post: Component<{ post: PostResponse }> = (props) => {
|
||||||
<IconButton>
|
<IconButton>
|
||||||
<ScreenRotationAlt/>
|
<ScreenRotationAlt/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton>
|
<IconButton onclick={handleFavorite}>
|
||||||
<Favorite/>
|
<Favorite/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Box sx={{marginLeft: "auto"}}>
|
<Box sx={{marginLeft: "auto"}}>
|
||||||
|
|
|
@ -35,7 +35,7 @@ class PostsTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val user = UserResponse(
|
val user = UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -45,7 +45,7 @@ class PostsTest {
|
||||||
)
|
)
|
||||||
val posts = listOf(
|
val posts = listOf(
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 12345,
|
id = "12345",
|
||||||
user = user,
|
user = user,
|
||||||
text = "test1",
|
text = "test1",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -53,7 +53,7 @@ class PostsTest {
|
||||||
url = "https://example.com/posts/1"
|
url = "https://example.com/posts/1"
|
||||||
),
|
),
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 123456,
|
id = "123456",
|
||||||
user = user,
|
user = user,
|
||||||
text = "test2",
|
text = "test2",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -78,7 +78,7 @@ class PostsTest {
|
||||||
configureSecurity(mock(), mock())
|
configureSecurity(mock(), mock())
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ class PostsTest {
|
||||||
on { getClaim(eq("uid")) } doReturn claim
|
on { getClaim(eq("uid")) } doReturn claim
|
||||||
}
|
}
|
||||||
val user = UserResponse(
|
val user = UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -111,7 +111,7 @@ class PostsTest {
|
||||||
)
|
)
|
||||||
val posts = listOf(
|
val posts = listOf(
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 12345,
|
id = "12345",
|
||||||
user = user,
|
user = user,
|
||||||
text = "test1",
|
text = "test1",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -119,7 +119,7 @@ class PostsTest {
|
||||||
url = "https://example.com/posts/1"
|
url = "https://example.com/posts/1"
|
||||||
),
|
),
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 123456,
|
id = "123456",
|
||||||
user = user,
|
user = user,
|
||||||
text = "test2",
|
text = "test2",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -127,7 +127,7 @@ class PostsTest {
|
||||||
url = "https://example.com/posts/2"
|
url = "https://example.com/posts/2"
|
||||||
),
|
),
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 1234567,
|
id = "1234567",
|
||||||
user = user,
|
user = user,
|
||||||
text = "Followers only",
|
text = "Followers only",
|
||||||
visibility = Visibility.FOLLOWERS,
|
visibility = Visibility.FOLLOWERS,
|
||||||
|
@ -159,7 +159,7 @@ class PostsTest {
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ class PostsTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val user = UserResponse(
|
val user = UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -185,7 +185,7 @@ class PostsTest {
|
||||||
createdAt = Instant.now().toEpochMilli()
|
createdAt = Instant.now().toEpochMilli()
|
||||||
)
|
)
|
||||||
val post = PostResponse(
|
val post = PostResponse(
|
||||||
id = 12345,
|
id = "12345",
|
||||||
user = user,
|
user = user,
|
||||||
text = "aaa",
|
text = "aaa",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -200,7 +200,7 @@ class PostsTest {
|
||||||
configureSecurity(mock(), mock())
|
configureSecurity(mock(), mock())
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,9 +216,9 @@ class PostsTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val post = PostResponse(
|
val post = PostResponse(
|
||||||
12345,
|
"12345",
|
||||||
UserResponse(
|
UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -251,7 +251,7 @@ class PostsTest {
|
||||||
}
|
}
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,9 +279,9 @@ class PostsTest {
|
||||||
val argument = it.getArgument<dev.usbharu.hideout.domain.model.hideout.form.Post>(0)
|
val argument = it.getArgument<dev.usbharu.hideout.domain.model.hideout.form.Post>(0)
|
||||||
val userId = it.getArgument<Long>(1)
|
val userId = it.getArgument<Long>(1)
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 123L,
|
id = "123",
|
||||||
user = UserResponse(
|
user = UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -308,7 +308,7 @@ class PostsTest {
|
||||||
}
|
}
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
|
@ -335,7 +335,7 @@ class PostsTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val user = UserResponse(
|
val user = UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -345,7 +345,7 @@ class PostsTest {
|
||||||
)
|
)
|
||||||
val posts = listOf(
|
val posts = listOf(
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 12345,
|
id = "12345",
|
||||||
user = user,
|
user = user,
|
||||||
text = "test1",
|
text = "test1",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -353,7 +353,7 @@ class PostsTest {
|
||||||
url = "https://example.com/posts/1"
|
url = "https://example.com/posts/1"
|
||||||
),
|
),
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 123456,
|
id = "123456",
|
||||||
user = user,
|
user = user,
|
||||||
text = "test2",
|
text = "test2",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -379,7 +379,7 @@ class PostsTest {
|
||||||
configureSecurity(mock(), mock())
|
configureSecurity(mock(), mock())
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -396,7 +396,7 @@ class PostsTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val user = UserResponse(
|
val user = UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -406,7 +406,7 @@ class PostsTest {
|
||||||
)
|
)
|
||||||
val posts = listOf(
|
val posts = listOf(
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 12345,
|
id = "12345",
|
||||||
user = user,
|
user = user,
|
||||||
text = "test1",
|
text = "test1",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -414,7 +414,7 @@ class PostsTest {
|
||||||
url = "https://example.com/posts/1"
|
url = "https://example.com/posts/1"
|
||||||
),
|
),
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 123456,
|
id = "123456",
|
||||||
user = user,
|
user = user,
|
||||||
text = "test2",
|
text = "test2",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -440,7 +440,7 @@ class PostsTest {
|
||||||
configureSecurity(mock(), mock())
|
configureSecurity(mock(), mock())
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -457,7 +457,7 @@ class PostsTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val user = UserResponse(
|
val user = UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -467,7 +467,7 @@ class PostsTest {
|
||||||
)
|
)
|
||||||
val posts = listOf(
|
val posts = listOf(
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 12345,
|
id = "12345",
|
||||||
user = user,
|
user = user,
|
||||||
text = "test1",
|
text = "test1",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -475,7 +475,7 @@ class PostsTest {
|
||||||
url = "https://example.com/posts/1"
|
url = "https://example.com/posts/1"
|
||||||
),
|
),
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 123456,
|
id = "123456",
|
||||||
user = user,
|
user = user,
|
||||||
text = "test2",
|
text = "test2",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -501,7 +501,7 @@ class PostsTest {
|
||||||
configureSecurity(mock(), mock())
|
configureSecurity(mock(), mock())
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -518,7 +518,7 @@ class PostsTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val user = UserResponse(
|
val user = UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -528,7 +528,7 @@ class PostsTest {
|
||||||
)
|
)
|
||||||
val posts = listOf(
|
val posts = listOf(
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 12345,
|
id = "12345",
|
||||||
user = user,
|
user = user,
|
||||||
text = "test1",
|
text = "test1",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -536,7 +536,7 @@ class PostsTest {
|
||||||
url = "https://example.com/posts/1"
|
url = "https://example.com/posts/1"
|
||||||
),
|
),
|
||||||
PostResponse(
|
PostResponse(
|
||||||
id = 123456,
|
id = "123456",
|
||||||
user = user,
|
user = user,
|
||||||
text = "test2",
|
text = "test2",
|
||||||
visibility = Visibility.PUBLIC,
|
visibility = Visibility.PUBLIC,
|
||||||
|
@ -562,7 +562,7 @@ class PostsTest {
|
||||||
configureSecurity(mock(), mock())
|
configureSecurity(mock(), mock())
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -579,9 +579,9 @@ class PostsTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val post = PostResponse(
|
val post = PostResponse(
|
||||||
id = 123456,
|
id = "123456",
|
||||||
user = UserResponse(
|
user = UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -602,7 +602,7 @@ class PostsTest {
|
||||||
configureSecurity(mock(), mock())
|
configureSecurity(mock(), mock())
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -619,9 +619,9 @@ class PostsTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val post = PostResponse(
|
val post = PostResponse(
|
||||||
id = 123456,
|
id = "123456",
|
||||||
user = UserResponse(
|
user = UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -642,7 +642,7 @@ class PostsTest {
|
||||||
configureSecurity(mock(), mock())
|
configureSecurity(mock(), mock())
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -659,9 +659,9 @@ class PostsTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val post = PostResponse(
|
val post = PostResponse(
|
||||||
id = 123456,
|
id = "123456",
|
||||||
user = UserResponse(
|
user = UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -682,7 +682,7 @@ class PostsTest {
|
||||||
configureSecurity(mock(), mock())
|
configureSecurity(mock(), mock())
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -699,9 +699,9 @@ class PostsTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val post = PostResponse(
|
val post = PostResponse(
|
||||||
id = 123456,
|
id = "123456",
|
||||||
user = UserResponse(
|
user = UserResponse(
|
||||||
id = 54321,
|
id = "54321",
|
||||||
name = "user1",
|
name = "user1",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
screenName = "user 1",
|
screenName = "user 1",
|
||||||
|
@ -722,7 +722,7 @@ class PostsTest {
|
||||||
configureSecurity(mock(), mock())
|
configureSecurity(mock(), mock())
|
||||||
routing {
|
routing {
|
||||||
route("/api/internal/v1") {
|
route("/api/internal/v1") {
|
||||||
posts(postService)
|
posts(postService, mock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import org.mockito.kotlin.*
|
||||||
import utils.JsonObjectMapper
|
import utils.JsonObjectMapper
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
@Suppress("LargeClass")
|
||||||
class UsersTest {
|
class UsersTest {
|
||||||
@Test
|
@Test
|
||||||
fun `users にGETするとユーザー一覧を取得できる`() = testApplication {
|
fun `users にGETするとユーザー一覧を取得できる`() = testApplication {
|
||||||
|
@ -35,7 +35,7 @@ class UsersTest {
|
||||||
|
|
||||||
val users = listOf(
|
val users = listOf(
|
||||||
UserResponse(
|
UserResponse(
|
||||||
12345,
|
"12345",
|
||||||
"test1",
|
"test1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -44,7 +44,7 @@ class UsersTest {
|
||||||
Instant.now().toEpochMilli()
|
Instant.now().toEpochMilli()
|
||||||
),
|
),
|
||||||
UserResponse(
|
UserResponse(
|
||||||
12343,
|
"12343",
|
||||||
"tes2",
|
"tes2",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -149,7 +149,7 @@ class UsersTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val userResponse = UserResponse(
|
val userResponse = UserResponse(
|
||||||
1234,
|
"1234",
|
||||||
"test1",
|
"test1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -182,7 +182,7 @@ class UsersTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val userResponse = UserResponse(
|
val userResponse = UserResponse(
|
||||||
1234,
|
"1234",
|
||||||
"test1",
|
"test1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -215,7 +215,7 @@ class UsersTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val userResponse = UserResponse(
|
val userResponse = UserResponse(
|
||||||
1234,
|
"1234",
|
||||||
"test1",
|
"test1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -248,7 +248,7 @@ class UsersTest {
|
||||||
config = ApplicationConfig("empty.conf")
|
config = ApplicationConfig("empty.conf")
|
||||||
}
|
}
|
||||||
val userResponse = UserResponse(
|
val userResponse = UserResponse(
|
||||||
1234,
|
"1234",
|
||||||
"test1",
|
"test1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -283,7 +283,7 @@ class UsersTest {
|
||||||
|
|
||||||
val followers = listOf(
|
val followers = listOf(
|
||||||
UserResponse(
|
UserResponse(
|
||||||
1235,
|
"1235",
|
||||||
"follower1",
|
"follower1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -292,7 +292,7 @@ class UsersTest {
|
||||||
Instant.now().toEpochMilli()
|
Instant.now().toEpochMilli()
|
||||||
),
|
),
|
||||||
UserResponse(
|
UserResponse(
|
||||||
1236,
|
"1236",
|
||||||
"follower2",
|
"follower2",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -328,7 +328,7 @@ class UsersTest {
|
||||||
|
|
||||||
val followers = listOf(
|
val followers = listOf(
|
||||||
UserResponse(
|
UserResponse(
|
||||||
1235,
|
"1235",
|
||||||
"follower1",
|
"follower1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -337,7 +337,7 @@ class UsersTest {
|
||||||
Instant.now().toEpochMilli()
|
Instant.now().toEpochMilli()
|
||||||
),
|
),
|
||||||
UserResponse(
|
UserResponse(
|
||||||
1236,
|
"1236",
|
||||||
"follower2",
|
"follower2",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -373,7 +373,7 @@ class UsersTest {
|
||||||
|
|
||||||
val followers = listOf(
|
val followers = listOf(
|
||||||
UserResponse(
|
UserResponse(
|
||||||
1235,
|
"1235",
|
||||||
"follower1",
|
"follower1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -382,7 +382,7 @@ class UsersTest {
|
||||||
Instant.now().toEpochMilli()
|
Instant.now().toEpochMilli()
|
||||||
),
|
),
|
||||||
UserResponse(
|
UserResponse(
|
||||||
1236,
|
"1236",
|
||||||
"follower2",
|
"follower2",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -425,7 +425,7 @@ class UsersTest {
|
||||||
|
|
||||||
val userApiService = mock<IUserApiService> {
|
val userApiService = mock<IUserApiService> {
|
||||||
onBlocking { findByAcct(any()) } doReturn UserResponse(
|
onBlocking { findByAcct(any()) } doReturn UserResponse(
|
||||||
1235,
|
"1235",
|
||||||
"follower1",
|
"follower1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -475,7 +475,7 @@ class UsersTest {
|
||||||
|
|
||||||
val userApiService = mock<IUserApiService> {
|
val userApiService = mock<IUserApiService> {
|
||||||
onBlocking { findByAcct(any()) } doReturn UserResponse(
|
onBlocking { findByAcct(any()) } doReturn UserResponse(
|
||||||
1235,
|
"1235",
|
||||||
"follower1",
|
"follower1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -525,7 +525,7 @@ class UsersTest {
|
||||||
|
|
||||||
val userApiService = mock<IUserApiService> {
|
val userApiService = mock<IUserApiService> {
|
||||||
onBlocking { findById(any()) } doReturn UserResponse(
|
onBlocking { findById(any()) } doReturn UserResponse(
|
||||||
1235,
|
"1235",
|
||||||
"follower1",
|
"follower1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -568,7 +568,7 @@ class UsersTest {
|
||||||
|
|
||||||
val followers = listOf(
|
val followers = listOf(
|
||||||
UserResponse(
|
UserResponse(
|
||||||
1235,
|
"1235",
|
||||||
"follower1",
|
"follower1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -577,7 +577,7 @@ class UsersTest {
|
||||||
Instant.now().toEpochMilli()
|
Instant.now().toEpochMilli()
|
||||||
),
|
),
|
||||||
UserResponse(
|
UserResponse(
|
||||||
1236,
|
"1236",
|
||||||
"follower2",
|
"follower2",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -613,7 +613,7 @@ class UsersTest {
|
||||||
|
|
||||||
val followers = listOf(
|
val followers = listOf(
|
||||||
UserResponse(
|
UserResponse(
|
||||||
1235,
|
"1235",
|
||||||
"follower1",
|
"follower1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -622,7 +622,7 @@ class UsersTest {
|
||||||
Instant.now().toEpochMilli()
|
Instant.now().toEpochMilli()
|
||||||
),
|
),
|
||||||
UserResponse(
|
UserResponse(
|
||||||
1236,
|
"1236",
|
||||||
"follower2",
|
"follower2",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -658,7 +658,7 @@ class UsersTest {
|
||||||
|
|
||||||
val followers = listOf(
|
val followers = listOf(
|
||||||
UserResponse(
|
UserResponse(
|
||||||
1235,
|
"1235",
|
||||||
"follower1",
|
"follower1",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
@ -667,7 +667,7 @@ class UsersTest {
|
||||||
Instant.now().toEpochMilli()
|
Instant.now().toEpochMilli()
|
||||||
),
|
),
|
||||||
UserResponse(
|
UserResponse(
|
||||||
1236,
|
"1236",
|
||||||
"follower2",
|
"follower2",
|
||||||
"example.com",
|
"example.com",
|
||||||
"test",
|
"test",
|
||||||
|
|
Loading…
Reference in New Issue