mirror of https://github.com/usbharu/Hideout.git
Merge pull request #94 from usbharu/feature/entity-builder
Feature/entity builder
This commit is contained in:
commit
8347bd7d0f
|
@ -1,64 +0,0 @@
|
||||||
package dev.usbharu.hideout.config
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
|
||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
|
||||||
|
|
||||||
@Deprecated("Config is deprecated")
|
|
||||||
object Config {
|
|
||||||
var configData: ConfigData = ConfigData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated("Config is deprecated")
|
|
||||||
data class ConfigData(
|
|
||||||
val url: String = "",
|
|
||||||
val domain: String = url.substringAfter("://").substringBeforeLast(":"),
|
|
||||||
val objectMapper: ObjectMapper = jacksonObjectMapper(),
|
|
||||||
val characterLimit: CharacterLimit = CharacterLimit()
|
|
||||||
)
|
|
||||||
|
|
||||||
@Deprecated("Config is deprecated")
|
|
||||||
data class CharacterLimit(
|
|
||||||
val general: General = General.of(),
|
|
||||||
val post: Post = Post(),
|
|
||||||
val account: Account = Account(),
|
|
||||||
val instance: Instance = Instance()
|
|
||||||
) {
|
|
||||||
@Deprecated("Config is deprecated")
|
|
||||||
data class General private constructor(
|
|
||||||
val url: Int,
|
|
||||||
val domain: Int,
|
|
||||||
val publicKey: Int,
|
|
||||||
val privateKey: Int
|
|
||||||
) {
|
|
||||||
companion object {
|
|
||||||
@Suppress("FunctionMinLength")
|
|
||||||
fun of(url: Int? = null, domain: Int? = null, publicKey: Int? = null, privateKey: Int? = null): General {
|
|
||||||
return General(
|
|
||||||
url ?: 1000,
|
|
||||||
domain ?: 1000,
|
|
||||||
publicKey ?: 10000,
|
|
||||||
privateKey ?: 10000
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated("Config is deprecated")
|
|
||||||
data class Post(
|
|
||||||
val text: Int = 3000,
|
|
||||||
val overview: Int = 3000
|
|
||||||
)
|
|
||||||
|
|
||||||
@Deprecated("Config is deprecated")
|
|
||||||
data class Account(
|
|
||||||
val id: Int = 300,
|
|
||||||
val name: Int = 300,
|
|
||||||
val description: Int = 10000
|
|
||||||
)
|
|
||||||
|
|
||||||
@Deprecated("Config is deprecated")
|
|
||||||
data class Instance(
|
|
||||||
val name: Int = 600,
|
|
||||||
val description: Int = 10000
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -43,3 +43,35 @@ data class StorageConfig(
|
||||||
val accessKey: String,
|
val accessKey: String,
|
||||||
val secretKey: String
|
val secretKey: String
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ConfigurationProperties("hideout.character-limit")
|
||||||
|
data class CharacterLimit(
|
||||||
|
val general: General = General(),
|
||||||
|
val post: Post = Post(),
|
||||||
|
val account: Account = Account(),
|
||||||
|
val instance: Instance = Instance()
|
||||||
|
) {
|
||||||
|
|
||||||
|
data class General(
|
||||||
|
val url: Int = 1000,
|
||||||
|
val domain: Int = 1000,
|
||||||
|
val publicKey: Int = 10000,
|
||||||
|
val privateKey: Int = 10000
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Post(
|
||||||
|
val text: Int = 3000,
|
||||||
|
val overview: Int = 3000
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Account(
|
||||||
|
val id: Int = 300,
|
||||||
|
val name: Int = 300,
|
||||||
|
val description: Int = 10000
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Instance(
|
||||||
|
val name: Int = 600,
|
||||||
|
val description: Int = 10000
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package dev.usbharu.hideout.domain.model.hideout.entity
|
package dev.usbharu.hideout.domain.model.hideout.entity
|
||||||
|
|
||||||
import dev.usbharu.hideout.config.Config
|
import dev.usbharu.hideout.config.CharacterLimit
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
data class Post private constructor(
|
data class Post private constructor(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
|
@ -16,7 +17,9 @@ data class Post private constructor(
|
||||||
val apId: String = url,
|
val apId: String = url,
|
||||||
val mediaIds: List<Long> = emptyList()
|
val mediaIds: List<Long> = emptyList()
|
||||||
) {
|
) {
|
||||||
companion object {
|
|
||||||
|
@Component
|
||||||
|
class PostBuilder(private val characterLimit: CharacterLimit) {
|
||||||
@Suppress("FunctionMinLength", "LongParameterList")
|
@Suppress("FunctionMinLength", "LongParameterList")
|
||||||
fun of(
|
fun of(
|
||||||
id: Long,
|
id: Long,
|
||||||
|
@ -32,8 +35,6 @@ data class Post private constructor(
|
||||||
apId: String = url,
|
apId: String = url,
|
||||||
mediaIds: List<Long> = emptyList()
|
mediaIds: List<Long> = emptyList()
|
||||||
): Post {
|
): Post {
|
||||||
val characterLimit = Config.configData.characterLimit
|
|
||||||
|
|
||||||
require(id >= 0) { "id must be greater than or equal to 0." }
|
require(id >= 0) { "id must be greater than or equal to 0." }
|
||||||
|
|
||||||
require(userId >= 0) { "userId must be greater than or equal to 0." }
|
require(userId >= 0) { "userId must be greater than or equal to 0." }
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package dev.usbharu.hideout.domain.model.hideout.entity
|
package dev.usbharu.hideout.domain.model.hideout.entity
|
||||||
|
|
||||||
import dev.usbharu.hideout.config.Config
|
import dev.usbharu.hideout.config.ApplicationConfig
|
||||||
|
import dev.usbharu.hideout.config.CharacterLimit
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
data class User private constructor(
|
data class User private constructor(
|
||||||
|
@ -27,9 +29,9 @@ data class User private constructor(
|
||||||
" privateKey=$privateKey, createdAt=$createdAt, keyId='$keyId', followers=$followers," +
|
" privateKey=$privateKey, createdAt=$createdAt, keyId='$keyId', followers=$followers," +
|
||||||
" following=$following)"
|
" following=$following)"
|
||||||
|
|
||||||
companion object {
|
@Component
|
||||||
|
class UserBuilder(private val characterLimit: CharacterLimit, private val applicationConfig: ApplicationConfig) {
|
||||||
private val logger = LoggerFactory.getLogger(User::class.java)
|
private val logger = LoggerFactory.getLogger(UserBuilder::class.java)
|
||||||
|
|
||||||
@Suppress("LongParameterList", "FunctionMinLength", "LongMethod")
|
@Suppress("LongParameterList", "FunctionMinLength", "LongMethod")
|
||||||
fun of(
|
fun of(
|
||||||
|
@ -49,8 +51,6 @@ data class User private constructor(
|
||||||
following: String? = null,
|
following: String? = null,
|
||||||
followers: String? = null
|
followers: String? = null
|
||||||
): User {
|
): User {
|
||||||
val characterLimit = Config.configData.characterLimit
|
|
||||||
|
|
||||||
// idは0未満ではいけない
|
// idは0未満ではいけない
|
||||||
require(id >= 0) { "id must be greater than or equal to 0." }
|
require(id >= 0) { "id must be greater than or equal to 0." }
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ data class User private constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ローカルユーザーはpasswordとprivateKeyをnullにしてはいけない
|
// ローカルユーザーはpasswordとprivateKeyをnullにしてはいけない
|
||||||
if (domain == Config.configData.domain) {
|
if (domain == applicationConfig.url.host) {
|
||||||
requireNotNull(password) { "password and privateKey must not be null for local users." }
|
requireNotNull(password) { "password and privateKey must not be null for local users." }
|
||||||
requireNotNull(privateKey) { "password and privateKey must not be null for local users." }
|
requireNotNull(privateKey) { "password and privateKey must not be null for local users." }
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import org.springframework.stereotype.Repository
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
class FollowerQueryServiceImpl : FollowerQueryService {
|
class FollowerQueryServiceImpl(private val userBuilder: User.UserBuilder) : FollowerQueryService {
|
||||||
override suspend fun findFollowersById(id: Long): List<User> {
|
override suspend fun findFollowersById(id: Long): List<User> {
|
||||||
val followers = Users.alias("FOLLOWERS")
|
val followers = Users.alias("FOLLOWERS")
|
||||||
return Users.innerJoin(
|
return Users.innerJoin(
|
||||||
|
@ -41,7 +41,7 @@ class FollowerQueryServiceImpl : FollowerQueryService {
|
||||||
)
|
)
|
||||||
.select { Users.id eq id }
|
.select { Users.id eq id }
|
||||||
.map {
|
.map {
|
||||||
User.of(
|
userBuilder.of(
|
||||||
id = it[followers[Users.id]],
|
id = it[followers[Users.id]],
|
||||||
name = it[followers[Users.name]],
|
name = it[followers[Users.name]],
|
||||||
domain = it[followers[Users.domain]],
|
domain = it[followers[Users.domain]],
|
||||||
|
@ -92,7 +92,7 @@ class FollowerQueryServiceImpl : FollowerQueryService {
|
||||||
)
|
)
|
||||||
.select { Users.name eq name and (Users.domain eq domain) }
|
.select { Users.name eq name and (Users.domain eq domain) }
|
||||||
.map {
|
.map {
|
||||||
User.of(
|
userBuilder.of(
|
||||||
id = it[followers[Users.id]],
|
id = it[followers[Users.id]],
|
||||||
name = it[followers[Users.name]],
|
name = it[followers[Users.name]],
|
||||||
domain = it[followers[Users.domain]],
|
domain = it[followers[Users.domain]],
|
||||||
|
@ -143,7 +143,7 @@ class FollowerQueryServiceImpl : FollowerQueryService {
|
||||||
)
|
)
|
||||||
.select { followers[Users.id] eq id }
|
.select { followers[Users.id] eq id }
|
||||||
.map {
|
.map {
|
||||||
User.of(
|
userBuilder.of(
|
||||||
id = it[followers[Users.id]],
|
id = it[followers[Users.id]],
|
||||||
name = it[followers[Users.name]],
|
name = it[followers[Users.name]],
|
||||||
domain = it[followers[Users.domain]],
|
domain = it[followers[Users.domain]],
|
||||||
|
@ -194,7 +194,7 @@ class FollowerQueryServiceImpl : FollowerQueryService {
|
||||||
)
|
)
|
||||||
.select { followers[Users.name] eq name and (followers[Users.domain] eq domain) }
|
.select { followers[Users.name] eq name and (followers[Users.domain] eq domain) }
|
||||||
.map {
|
.map {
|
||||||
User.of(
|
userBuilder.of(
|
||||||
id = it[followers[Users.id]],
|
id = it[followers[Users.id]],
|
||||||
name = it[followers[Users.name]],
|
name = it[followers[Users.name]],
|
||||||
domain = it[followers[Users.domain]],
|
domain = it[followers[Users.domain]],
|
||||||
|
|
|
@ -4,27 +4,32 @@ import dev.usbharu.hideout.domain.model.hideout.entity.Post
|
||||||
import dev.usbharu.hideout.exception.FailedToGetResourcesException
|
import dev.usbharu.hideout.exception.FailedToGetResourcesException
|
||||||
import dev.usbharu.hideout.repository.Posts
|
import dev.usbharu.hideout.repository.Posts
|
||||||
import dev.usbharu.hideout.repository.PostsMedia
|
import dev.usbharu.hideout.repository.PostsMedia
|
||||||
import dev.usbharu.hideout.repository.toPost
|
import dev.usbharu.hideout.repository.QueryMapper
|
||||||
|
import dev.usbharu.hideout.repository.ResultRowMapper
|
||||||
import dev.usbharu.hideout.util.singleOr
|
import dev.usbharu.hideout.util.singleOr
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.springframework.stereotype.Repository
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
class PostQueryServiceImpl : PostQueryService {
|
class PostQueryServiceImpl(
|
||||||
|
private val postResultRowMapper: ResultRowMapper<Post>,
|
||||||
|
private val postQueryMapper: QueryMapper<Post>
|
||||||
|
) : PostQueryService {
|
||||||
override suspend fun findById(id: Long): Post =
|
override suspend fun findById(id: Long): Post =
|
||||||
Posts.leftJoin(PostsMedia)
|
Posts.leftJoin(PostsMedia)
|
||||||
.select { Posts.id eq id }
|
.select { Posts.id eq id }
|
||||||
.singleOr { FailedToGetResourcesException("id: $id is duplicate or does not exist.", it) }.toPost()
|
.singleOr { FailedToGetResourcesException("id: $id is duplicate or does not exist.", it) }
|
||||||
|
.let(postResultRowMapper::map)
|
||||||
|
|
||||||
override suspend fun findByUrl(url: String): Post =
|
override suspend fun findByUrl(url: String): Post =
|
||||||
Posts.leftJoin(PostsMedia)
|
Posts.leftJoin(PostsMedia)
|
||||||
.select { Posts.url eq url }
|
.select { Posts.url eq url }
|
||||||
.toPost()
|
.let(postQueryMapper::map)
|
||||||
.singleOr { FailedToGetResourcesException("url: $url is duplicate or does not exist.", it) }
|
.singleOr { FailedToGetResourcesException("url: $url is duplicate or does not exist.", it) }
|
||||||
|
|
||||||
override suspend fun findByApId(string: String): Post =
|
override suspend fun findByApId(string: String): Post =
|
||||||
Posts.leftJoin(PostsMedia)
|
Posts.leftJoin(PostsMedia)
|
||||||
.select { Posts.apId eq string }
|
.select { Posts.apId eq string }
|
||||||
.toPost()
|
.let(postQueryMapper::map)
|
||||||
.singleOr { FailedToGetResourcesException("apId: $string is duplicate or does not exist.", it) }
|
.singleOr { FailedToGetResourcesException("apId: $string is duplicate or does not exist.", it) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@ package dev.usbharu.hideout.query
|
||||||
|
|
||||||
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
||||||
import dev.usbharu.hideout.exception.FailedToGetResourcesException
|
import dev.usbharu.hideout.exception.FailedToGetResourcesException
|
||||||
|
import dev.usbharu.hideout.repository.QueryMapper
|
||||||
|
import dev.usbharu.hideout.repository.ResultRowMapper
|
||||||
import dev.usbharu.hideout.repository.Users
|
import dev.usbharu.hideout.repository.Users
|
||||||
import dev.usbharu.hideout.repository.toUser
|
|
||||||
import dev.usbharu.hideout.util.singleOr
|
import dev.usbharu.hideout.util.singleOr
|
||||||
import org.jetbrains.exposed.sql.and
|
import org.jetbrains.exposed.sql.and
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
|
@ -12,17 +13,22 @@ import org.slf4j.LoggerFactory
|
||||||
import org.springframework.stereotype.Repository
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
class UserQueryServiceImpl : UserQueryService {
|
class UserQueryServiceImpl(
|
||||||
|
private val userResultRowMapper: ResultRowMapper<User>,
|
||||||
|
private val userQueryMapper: QueryMapper<User>
|
||||||
|
) : UserQueryService {
|
||||||
|
|
||||||
private val logger = LoggerFactory.getLogger(UserQueryServiceImpl::class.java)
|
private val logger = LoggerFactory.getLogger(UserQueryServiceImpl::class.java)
|
||||||
|
|
||||||
override suspend fun findAll(limit: Int, offset: Long): List<User> =
|
override suspend fun findAll(limit: Int, offset: Long): List<User> =
|
||||||
Users.selectAll().limit(limit, offset).map { it.toUser() }
|
Users.selectAll().limit(limit, offset).let(userQueryMapper::map)
|
||||||
|
|
||||||
override suspend fun findById(id: Long): User = Users.select { Users.id eq id }
|
override suspend fun findById(id: Long): User = Users.select { Users.id eq id }
|
||||||
.singleOr { FailedToGetResourcesException("id: $id is duplicate or does not exist.", it) }.toUser()
|
.singleOr { FailedToGetResourcesException("id: $id is duplicate or does not exist.", it) }
|
||||||
|
.let(userResultRowMapper::map)
|
||||||
|
|
||||||
override suspend fun findByName(name: String): List<User> = Users.select { Users.name eq name }.map { it.toUser() }
|
override suspend fun findByName(name: String): List<User> =
|
||||||
|
Users.select { Users.name eq name }.let(userQueryMapper::map)
|
||||||
|
|
||||||
override suspend fun findByNameAndDomain(name: String, domain: String): User =
|
override suspend fun findByNameAndDomain(name: String, domain: String): User =
|
||||||
Users
|
Users
|
||||||
|
@ -30,17 +36,17 @@ class UserQueryServiceImpl : UserQueryService {
|
||||||
.singleOr {
|
.singleOr {
|
||||||
FailedToGetResourcesException("name: $name,domain: $domain is duplicate or does not exist.", it)
|
FailedToGetResourcesException("name: $name,domain: $domain is duplicate or does not exist.", it)
|
||||||
}
|
}
|
||||||
.toUser()
|
.let(userResultRowMapper::map)
|
||||||
|
|
||||||
override suspend fun findByUrl(url: String): User {
|
override suspend fun findByUrl(url: String): User {
|
||||||
logger.trace("findByUrl url: $url")
|
logger.trace("findByUrl url: $url")
|
||||||
return Users.select { Users.url eq url }
|
return Users.select { Users.url eq url }
|
||||||
.singleOr { FailedToGetResourcesException("url: $url is duplicate or does not exist.", it) }
|
.singleOr { FailedToGetResourcesException("url: $url is duplicate or does not exist.", it) }
|
||||||
.toUser()
|
.let(userResultRowMapper::map)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByIds(ids: List<Long>): List<User> =
|
override suspend fun findByIds(ids: List<Long>): List<User> =
|
||||||
Users.select { Users.id inList ids }.map { it.toUser() }
|
Users.select { Users.id inList ids }.let(userQueryMapper::map)
|
||||||
|
|
||||||
override suspend fun existByNameAndDomain(name: String, domain: String): Boolean =
|
override suspend fun existByNameAndDomain(name: String, domain: String): Boolean =
|
||||||
Users.select { Users.name eq name and (Users.domain eq domain) }.empty().not()
|
Users.select { Users.name eq name and (Users.domain eq domain) }.empty().not()
|
||||||
|
@ -48,6 +54,6 @@ class UserQueryServiceImpl : UserQueryService {
|
||||||
override suspend fun findByKeyId(keyId: String): User {
|
override suspend fun findByKeyId(keyId: String): User {
|
||||||
return Users.select { Users.keyId eq keyId }
|
return Users.select { Users.keyId eq keyId }
|
||||||
.singleOr { FailedToGetResourcesException("keyId: $keyId is duplicate or does not exist.", it) }
|
.singleOr { FailedToGetResourcesException("keyId: $keyId is duplicate or does not exist.", it) }
|
||||||
.toUser()
|
.let(userResultRowMapper::map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,15 @@ import org.springframework.stereotype.Repository
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
class NoteQueryServiceImpl(private val postRepository: PostRepository) : NoteQueryService {
|
class NoteQueryServiceImpl(private val postRepository: PostRepository, private val postQueryMapper: QueryMapper<Post>) :
|
||||||
|
NoteQueryService {
|
||||||
override suspend fun findById(id: Long): Pair<Note, Post> {
|
override suspend fun findById(id: Long): Pair<Note, Post> {
|
||||||
return Posts
|
return Posts
|
||||||
.leftJoin(Users)
|
.leftJoin(Users)
|
||||||
.leftJoin(PostsMedia)
|
.leftJoin(PostsMedia)
|
||||||
.leftJoin(Media)
|
.leftJoin(Media)
|
||||||
.select { Posts.id eq id }
|
.select { Posts.id eq id }
|
||||||
.let { it.toNote() to it.toPost().first() }
|
.let { it.toNote() to postQueryMapper.map(it).first() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun ResultRow.toNote(mediaList: List<dev.usbharu.hideout.domain.model.hideout.entity.Media>): Note {
|
private suspend fun ResultRow.toNote(mediaList: List<dev.usbharu.hideout.domain.model.hideout.entity.Media>): Note {
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package dev.usbharu.hideout.repository
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.Post
|
||||||
|
import org.jetbrains.exposed.sql.Query
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class PostQueryMapper(private val postResultRowMapper: ResultRowMapper<Post>) : QueryMapper<Post> {
|
||||||
|
override fun map(query: Query): List<Post> {
|
||||||
|
return query.groupBy { it[Posts.id] }
|
||||||
|
.map { it.value }
|
||||||
|
.map {
|
||||||
|
it.first().let(postResultRowMapper::map)
|
||||||
|
.copy(mediaIds = it.mapNotNull { it.getOrNull(PostsMedia.mediaId) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package dev.usbharu.hideout.repository
|
package dev.usbharu.hideout.repository
|
||||||
|
|
||||||
import dev.usbharu.hideout.domain.model.hideout.entity.Post
|
import dev.usbharu.hideout.domain.model.hideout.entity.Post
|
||||||
import dev.usbharu.hideout.domain.model.hideout.entity.Visibility
|
|
||||||
import dev.usbharu.hideout.exception.FailedToGetResourcesException
|
import dev.usbharu.hideout.exception.FailedToGetResourcesException
|
||||||
import dev.usbharu.hideout.service.core.IdGenerateService
|
import dev.usbharu.hideout.service.core.IdGenerateService
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
|
@ -9,7 +8,10 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
import org.springframework.stereotype.Repository
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
class PostRepositoryImpl(private val idGenerateService: IdGenerateService) : PostRepository {
|
class PostRepositoryImpl(
|
||||||
|
private val idGenerateService: IdGenerateService,
|
||||||
|
private val postQueryMapper: QueryMapper<Post>
|
||||||
|
) : PostRepository {
|
||||||
|
|
||||||
override suspend fun generateId(): Long = idGenerateService.generateId()
|
override suspend fun generateId(): Long = idGenerateService.generateId()
|
||||||
|
|
||||||
|
@ -65,7 +67,7 @@ class PostRepositoryImpl(private val idGenerateService: IdGenerateService) : Pos
|
||||||
override suspend fun findById(id: Long): Post =
|
override suspend fun findById(id: Long): Post =
|
||||||
Posts.innerJoin(PostsMedia, onColumn = { Posts.id }, otherColumn = { PostsMedia.postId })
|
Posts.innerJoin(PostsMedia, onColumn = { Posts.id }, otherColumn = { PostsMedia.postId })
|
||||||
.select { Posts.id eq id }
|
.select { Posts.id eq id }
|
||||||
.toPost()
|
.let(postQueryMapper::map)
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
?: throw FailedToGetResourcesException("id: $id was not found.")
|
?: throw FailedToGetResourcesException("id: $id was not found.")
|
||||||
|
|
||||||
|
@ -94,25 +96,3 @@ object PostsMedia : Table() {
|
||||||
val mediaId = long("media_id").references(Media.id, ReferenceOption.CASCADE, ReferenceOption.CASCADE)
|
val mediaId = long("media_id").references(Media.id, ReferenceOption.CASCADE, ReferenceOption.CASCADE)
|
||||||
override val primaryKey = PrimaryKey(postId, mediaId)
|
override val primaryKey = PrimaryKey(postId, mediaId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ResultRow.toPost(): Post {
|
|
||||||
return Post.of(
|
|
||||||
id = this[Posts.id],
|
|
||||||
userId = this[Posts.userId],
|
|
||||||
overview = this[Posts.overview],
|
|
||||||
text = this[Posts.text],
|
|
||||||
createdAt = this[Posts.createdAt],
|
|
||||||
visibility = Visibility.values().first { visibility -> visibility.ordinal == this[Posts.visibility] },
|
|
||||||
url = this[Posts.url],
|
|
||||||
repostId = this[Posts.repostId],
|
|
||||||
replyId = this[Posts.replyId],
|
|
||||||
sensitive = this[Posts.sensitive],
|
|
||||||
apId = this[Posts.apId],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Query.toPost(): List<Post> {
|
|
||||||
return this.groupBy { it[Posts.id] }
|
|
||||||
.map { it.value }
|
|
||||||
.map { it.first().toPost().copy(mediaIds = it.mapNotNull { it.getOrNull(PostsMedia.mediaId) }) }
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package dev.usbharu.hideout.repository
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.Post
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.Visibility
|
||||||
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class PostResultRowMapper(private val postBuilder: Post.PostBuilder) : ResultRowMapper<Post> {
|
||||||
|
override fun map(resultRow: ResultRow): Post {
|
||||||
|
return postBuilder.of(
|
||||||
|
id = resultRow[Posts.id],
|
||||||
|
userId = resultRow[Posts.userId],
|
||||||
|
overview = resultRow[Posts.overview],
|
||||||
|
text = resultRow[Posts.text],
|
||||||
|
createdAt = resultRow[Posts.createdAt],
|
||||||
|
visibility = Visibility.values().first { visibility -> visibility.ordinal == resultRow[Posts.visibility] },
|
||||||
|
url = resultRow[Posts.url],
|
||||||
|
repostId = resultRow[Posts.repostId],
|
||||||
|
replyId = resultRow[Posts.replyId],
|
||||||
|
sensitive = resultRow[Posts.sensitive],
|
||||||
|
apId = resultRow[Posts.apId],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package dev.usbharu.hideout.repository
|
||||||
|
|
||||||
|
import org.jetbrains.exposed.sql.Query
|
||||||
|
|
||||||
|
interface QueryMapper<T> {
|
||||||
|
fun map(query: Query): List<T>
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package dev.usbharu.hideout.repository
|
||||||
|
|
||||||
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
|
|
||||||
|
interface ResultRowMapper<T> {
|
||||||
|
fun map(resultRow: ResultRow): T
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package dev.usbharu.hideout.repository
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
||||||
|
import org.jetbrains.exposed.sql.Query
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class UserQueryMapper(private val userResultRowMapper: ResultRowMapper<User>) : QueryMapper<User> {
|
||||||
|
override fun map(query: Query): List<User> {
|
||||||
|
return query.map(userResultRowMapper::map)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +1,17 @@
|
||||||
package dev.usbharu.hideout.repository
|
package dev.usbharu.hideout.repository
|
||||||
|
|
||||||
import dev.usbharu.hideout.config.Config
|
|
||||||
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
||||||
import dev.usbharu.hideout.service.core.IdGenerateService
|
import dev.usbharu.hideout.service.core.IdGenerateService
|
||||||
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.SqlExpressionBuilder.eq
|
||||||
import org.springframework.stereotype.Repository
|
import org.springframework.stereotype.Repository
|
||||||
import java.time.Instant
|
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
class UserRepositoryImpl(private val idGenerateService: IdGenerateService) :
|
class UserRepositoryImpl(
|
||||||
|
private val idGenerateService: IdGenerateService,
|
||||||
|
private val userResultRowMapper: ResultRowMapper<User>
|
||||||
|
) :
|
||||||
UserRepository {
|
UserRepository {
|
||||||
|
|
||||||
override suspend fun save(user: User): User {
|
override suspend fun save(user: User): User {
|
||||||
|
@ -55,9 +56,7 @@ class UserRepositoryImpl(private val idGenerateService: IdGenerateService) :
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findById(id: Long): User? {
|
override suspend fun findById(id: Long): User? {
|
||||||
return Users.select { Users.id eq id }.map {
|
return Users.select { Users.id eq id }.singleOrNull()?.let(userResultRowMapper::map)
|
||||||
it.toUser()
|
|
||||||
}.singleOrNull()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deleteFollowRequest(id: Long, follower: Long) {
|
override suspend fun deleteFollowRequest(id: Long, follower: Long) {
|
||||||
|
@ -78,26 +77,26 @@ class UserRepositoryImpl(private val idGenerateService: IdGenerateService) :
|
||||||
|
|
||||||
object Users : Table("users") {
|
object Users : Table("users") {
|
||||||
val id: Column<Long> = long("id")
|
val id: Column<Long> = long("id")
|
||||||
val name: Column<String> = varchar("name", length = Config.configData.characterLimit.account.id)
|
val name: Column<String> = varchar("name", length = 300)
|
||||||
val domain: Column<String> = varchar("domain", length = Config.configData.characterLimit.general.domain)
|
val domain: Column<String> = varchar("domain", length = 1000)
|
||||||
val screenName: Column<String> = varchar("screen_name", length = Config.configData.characterLimit.account.name)
|
val screenName: Column<String> = varchar("screen_name", length = 300)
|
||||||
val description: Column<String> = varchar(
|
val description: Column<String> = varchar(
|
||||||
"description",
|
"description",
|
||||||
length = Config.configData.characterLimit.account.description
|
length = 10000
|
||||||
)
|
)
|
||||||
val password: Column<String?> = varchar("password", length = 255).nullable()
|
val password: Column<String?> = varchar("password", length = 255).nullable()
|
||||||
val inbox: Column<String> = varchar("inbox", length = Config.configData.characterLimit.general.url).uniqueIndex()
|
val inbox: Column<String> = varchar("inbox", length = 1000).uniqueIndex()
|
||||||
val outbox: Column<String> = varchar("outbox", length = Config.configData.characterLimit.general.url).uniqueIndex()
|
val outbox: Column<String> = varchar("outbox", length = 1000).uniqueIndex()
|
||||||
val url: Column<String> = varchar("url", length = Config.configData.characterLimit.general.url).uniqueIndex()
|
val url: Column<String> = varchar("url", length = 1000).uniqueIndex()
|
||||||
val publicKey: Column<String> = varchar("public_key", length = Config.configData.characterLimit.general.publicKey)
|
val publicKey: Column<String> = varchar("public_key", length = 10000)
|
||||||
val privateKey: Column<String?> = varchar(
|
val privateKey: Column<String?> = varchar(
|
||||||
"private_key",
|
"private_key",
|
||||||
length = Config.configData.characterLimit.general.privateKey
|
length = 10000
|
||||||
).nullable()
|
).nullable()
|
||||||
val createdAt: Column<Long> = long("created_at")
|
val createdAt: Column<Long> = long("created_at")
|
||||||
val keyId = varchar("key_id", length = Config.configData.characterLimit.general.url)
|
val keyId = varchar("key_id", length = 1000)
|
||||||
val following = varchar("following", length = Config.configData.characterLimit.general.url).nullable()
|
val following = varchar("following", length = 1000).nullable()
|
||||||
val followers = varchar("followers", length = Config.configData.characterLimit.general.url).nullable()
|
val followers = varchar("followers", length = 1000).nullable()
|
||||||
|
|
||||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||||
|
|
||||||
|
@ -106,26 +105,6 @@ object Users : Table("users") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ResultRow.toUser(): User {
|
|
||||||
return User.of(
|
|
||||||
id = this[Users.id],
|
|
||||||
name = this[Users.name],
|
|
||||||
domain = this[Users.domain],
|
|
||||||
screenName = this[Users.screenName],
|
|
||||||
description = this[Users.description],
|
|
||||||
password = this[Users.password],
|
|
||||||
inbox = this[Users.inbox],
|
|
||||||
outbox = this[Users.outbox],
|
|
||||||
url = this[Users.url],
|
|
||||||
publicKey = this[Users.publicKey],
|
|
||||||
privateKey = this[Users.privateKey],
|
|
||||||
createdAt = Instant.ofEpochMilli((this[Users.createdAt])),
|
|
||||||
keyId = this[Users.keyId],
|
|
||||||
followers = this[Users.followers],
|
|
||||||
following = this[Users.following]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
object UsersFollowers : LongIdTable("users_followers") {
|
object UsersFollowers : LongIdTable("users_followers") {
|
||||||
val userId: Column<Long> = long("user_id").references(Users.id).index()
|
val userId: Column<Long> = long("user_id").references(Users.id).index()
|
||||||
val followerId: Column<Long> = long("follower_id").references(Users.id)
|
val followerId: Column<Long> = long("follower_id").references(Users.id)
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package dev.usbharu.hideout.repository
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
||||||
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class UserResultRowMapper(private val userBuilder: User.UserBuilder) : ResultRowMapper<User> {
|
||||||
|
override fun map(resultRow: ResultRow): User {
|
||||||
|
return userBuilder.of(
|
||||||
|
id = resultRow[Users.id],
|
||||||
|
name = resultRow[Users.name],
|
||||||
|
domain = resultRow[Users.domain],
|
||||||
|
screenName = resultRow[Users.screenName],
|
||||||
|
description = resultRow[Users.description],
|
||||||
|
password = resultRow[Users.password],
|
||||||
|
inbox = resultRow[Users.inbox],
|
||||||
|
outbox = resultRow[Users.outbox],
|
||||||
|
url = resultRow[Users.url],
|
||||||
|
publicKey = resultRow[Users.publicKey],
|
||||||
|
privateKey = resultRow[Users.privateKey],
|
||||||
|
createdAt = Instant.ofEpochMilli((resultRow[Users.createdAt])),
|
||||||
|
keyId = resultRow[Users.keyId],
|
||||||
|
followers = resultRow[Users.followers],
|
||||||
|
following = resultRow[Users.following]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -69,6 +69,7 @@ class APNoteServiceImpl(
|
||||||
private val postService: PostService,
|
private val postService: PostService,
|
||||||
private val apResourceResolveService: APResourceResolveService,
|
private val apResourceResolveService: APResourceResolveService,
|
||||||
private val apRequestService: APRequestService,
|
private val apRequestService: APRequestService,
|
||||||
|
private val postBuilder: Post.PostBuilder,
|
||||||
private val transaction: Transaction
|
private val transaction: Transaction
|
||||||
|
|
||||||
) : APNoteService, PostCreateInterceptor {
|
) : APNoteService, PostCreateInterceptor {
|
||||||
|
@ -224,7 +225,7 @@ class APNoteServiceImpl(
|
||||||
|
|
||||||
// TODO: リモートのメディア処理を追加
|
// TODO: リモートのメディア処理を追加
|
||||||
postService.createRemote(
|
postService.createRemote(
|
||||||
Post.of(
|
postBuilder.of(
|
||||||
id = postRepository.generateId(),
|
id = postRepository.generateId(),
|
||||||
userId = person.second.id,
|
userId = person.second.id,
|
||||||
text = note.content.orEmpty(),
|
text = note.content.orEmpty(),
|
||||||
|
|
|
@ -16,7 +16,8 @@ class PostServiceImpl(
|
||||||
private val postRepository: PostRepository,
|
private val postRepository: PostRepository,
|
||||||
private val userRepository: UserRepository,
|
private val userRepository: UserRepository,
|
||||||
private val timelineService: TimelineService,
|
private val timelineService: TimelineService,
|
||||||
private val postQueryService: PostQueryService
|
private val postQueryService: PostQueryService,
|
||||||
|
private val postBuilder: Post.PostBuilder
|
||||||
) : PostService {
|
) : PostService {
|
||||||
private val interceptors = Collections.synchronizedList(mutableListOf<PostCreateInterceptor>())
|
private val interceptors = Collections.synchronizedList(mutableListOf<PostCreateInterceptor>())
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ class PostServiceImpl(
|
||||||
private suspend fun internalCreate(post: PostCreateDto, isLocal: Boolean): Post {
|
private suspend fun internalCreate(post: PostCreateDto, isLocal: Boolean): Post {
|
||||||
val user = userRepository.findById(post.userId) ?: throw UserNotFoundException("${post.userId} was not found")
|
val user = userRepository.findById(post.userId) ?: throw UserNotFoundException("${post.userId} was not found")
|
||||||
val id = postRepository.generateId()
|
val id = postRepository.generateId()
|
||||||
val createPost = Post.of(
|
val createPost = postBuilder.of(
|
||||||
id = id,
|
id = id,
|
||||||
userId = post.userId,
|
userId = post.userId,
|
||||||
overview = post.overview,
|
overview = post.overview,
|
||||||
|
|
|
@ -21,6 +21,7 @@ class UserServiceImpl(
|
||||||
private val apSendFollowService: APSendFollowService,
|
private val apSendFollowService: APSendFollowService,
|
||||||
private val userQueryService: UserQueryService,
|
private val userQueryService: UserQueryService,
|
||||||
private val followerQueryService: FollowerQueryService,
|
private val followerQueryService: FollowerQueryService,
|
||||||
|
private val userBuilder: User.UserBuilder,
|
||||||
private val applicationConfig: ApplicationConfig
|
private val applicationConfig: ApplicationConfig
|
||||||
) :
|
) :
|
||||||
UserService {
|
UserService {
|
||||||
|
@ -35,7 +36,7 @@ class UserServiceImpl(
|
||||||
val hashedPassword = userAuthService.hash(user.password)
|
val hashedPassword = userAuthService.hash(user.password)
|
||||||
val keyPair = userAuthService.generateKeyPair()
|
val keyPair = userAuthService.generateKeyPair()
|
||||||
val userUrl = "${applicationConfig.url}/users/${user.name}"
|
val userUrl = "${applicationConfig.url}/users/${user.name}"
|
||||||
val userEntity = User.of(
|
val userEntity = userBuilder.of(
|
||||||
id = nextId,
|
id = nextId,
|
||||||
name = user.name,
|
name = user.name,
|
||||||
domain = applicationConfig.url.host,
|
domain = applicationConfig.url.host,
|
||||||
|
@ -57,7 +58,7 @@ class UserServiceImpl(
|
||||||
|
|
||||||
override suspend fun createRemoteUser(user: RemoteUserCreateDto): User {
|
override suspend fun createRemoteUser(user: RemoteUserCreateDto): User {
|
||||||
val nextId = userRepository.nextId()
|
val nextId = userRepository.nextId()
|
||||||
val userEntity = User.of(
|
val userEntity = userBuilder.of(
|
||||||
id = nextId,
|
id = nextId,
|
||||||
name = user.name,
|
name = user.name,
|
||||||
domain = user.domain,
|
domain = user.domain,
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
package dev.usbharu.hideout.service.ap
|
package dev.usbharu.hideout.service.ap
|
||||||
|
|
||||||
import dev.usbharu.hideout.config.Config
|
import dev.usbharu.hideout.config.ApplicationConfig
|
||||||
import dev.usbharu.hideout.config.ConfigData
|
import dev.usbharu.hideout.config.CharacterLimit
|
||||||
import dev.usbharu.hideout.domain.model.hideout.entity.Post
|
import dev.usbharu.hideout.domain.model.hideout.entity.Post
|
||||||
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
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
|
||||||
|
@ -23,21 +23,28 @@ import org.junit.jupiter.api.Test
|
||||||
import org.mockito.Mockito.anyLong
|
import org.mockito.Mockito.anyLong
|
||||||
import org.mockito.Mockito.eq
|
import org.mockito.Mockito.eq
|
||||||
import org.mockito.kotlin.*
|
import org.mockito.kotlin.*
|
||||||
import utils.JsonObjectMapper
|
|
||||||
import utils.JsonObjectMapper.objectMapper
|
import utils.JsonObjectMapper.objectMapper
|
||||||
import utils.TestApplicationConfig.testApplicationConfig
|
import utils.TestApplicationConfig.testApplicationConfig
|
||||||
|
import java.net.URL
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class APNoteServiceImplTest {
|
class APNoteServiceImplTest {
|
||||||
|
|
||||||
|
val userBuilder = User.UserBuilder(CharacterLimit(), ApplicationConfig(URL("https://example.com")))
|
||||||
|
val postBuilder = Post.PostBuilder(CharacterLimit())
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `createPost 新しい投稿`() {
|
fun `createPost 新しい投稿`() {
|
||||||
val mediaQueryService = mock<MediaQueryService> {
|
val mediaQueryService = mock<MediaQueryService> {
|
||||||
onBlocking { findByPostId(anyLong()) } doReturn emptyList()
|
onBlocking { findByPostId(anyLong()) } doReturn emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
runTest {
|
runTest {
|
||||||
val followers = listOf(
|
val followers = listOf(
|
||||||
User.of(
|
userBuilder.of(
|
||||||
2L,
|
2L,
|
||||||
"follower",
|
"follower",
|
||||||
"follower.example.com",
|
"follower.example.com",
|
||||||
|
@ -51,7 +58,7 @@ class APNoteServiceImplTest {
|
||||||
createdAt = Instant.now(),
|
createdAt = Instant.now(),
|
||||||
keyId = "a"
|
keyId = "a"
|
||||||
),
|
),
|
||||||
User.of(
|
userBuilder.of(
|
||||||
3L,
|
3L,
|
||||||
"follower2",
|
"follower2",
|
||||||
"follower2.example.com",
|
"follower2.example.com",
|
||||||
|
@ -67,7 +74,7 @@ class APNoteServiceImplTest {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val userQueryService = mock<UserQueryService> {
|
val userQueryService = mock<UserQueryService> {
|
||||||
onBlocking { findById(eq(1L)) } doReturn User.of(
|
onBlocking { findById(eq(1L)) } doReturn userBuilder.of(
|
||||||
1L,
|
1L,
|
||||||
"test",
|
"test",
|
||||||
"example.com",
|
"example.com",
|
||||||
|
@ -101,9 +108,10 @@ class APNoteServiceImplTest {
|
||||||
postService = mock(),
|
postService = mock(),
|
||||||
apResourceResolveService = mock(),
|
apResourceResolveService = mock(),
|
||||||
apRequestService = mock(),
|
apRequestService = mock(),
|
||||||
transaction = mock()
|
transaction = mock(),
|
||||||
|
postBuilder = postBuilder
|
||||||
)
|
)
|
||||||
val postEntity = Post.of(
|
val postEntity = postBuilder.of(
|
||||||
1L,
|
1L,
|
||||||
1L,
|
1L,
|
||||||
null,
|
null,
|
||||||
|
@ -123,7 +131,7 @@ class APNoteServiceImplTest {
|
||||||
val mediaQueryService = mock<MediaQueryService> {
|
val mediaQueryService = mock<MediaQueryService> {
|
||||||
onBlocking { findByPostId(anyLong()) } doReturn emptyList()
|
onBlocking { findByPostId(anyLong()) } doReturn emptyList()
|
||||||
}
|
}
|
||||||
Config.configData = ConfigData(objectMapper = JsonObjectMapper.objectMapper)
|
|
||||||
val httpClient = HttpClient(
|
val httpClient = HttpClient(
|
||||||
MockEngine { httpRequestData ->
|
MockEngine { httpRequestData ->
|
||||||
assertEquals("https://follower.example.com/inbox", httpRequestData.url.toString())
|
assertEquals("https://follower.example.com/inbox", httpRequestData.url.toString())
|
||||||
|
@ -143,7 +151,8 @@ class APNoteServiceImplTest {
|
||||||
postService = mock(),
|
postService = mock(),
|
||||||
apResourceResolveService = mock(),
|
apResourceResolveService = mock(),
|
||||||
apRequestService = mock(),
|
apRequestService = mock(),
|
||||||
transaction = mock()
|
transaction = mock(),
|
||||||
|
postBuilder = postBuilder
|
||||||
)
|
)
|
||||||
activityPubNoteService.createNoteJob(
|
activityPubNoteService.createNoteJob(
|
||||||
JobProps(
|
JobProps(
|
||||||
|
|
|
@ -3,12 +3,13 @@
|
||||||
|
|
||||||
package dev.usbharu.hideout.service.ap
|
package dev.usbharu.hideout.service.ap
|
||||||
|
|
||||||
import dev.usbharu.hideout.config.Config
|
import dev.usbharu.hideout.config.ApplicationConfig
|
||||||
import dev.usbharu.hideout.config.ConfigData
|
import dev.usbharu.hideout.config.CharacterLimit
|
||||||
import dev.usbharu.hideout.domain.model.ap.Follow
|
import dev.usbharu.hideout.domain.model.ap.Follow
|
||||||
import dev.usbharu.hideout.domain.model.ap.Image
|
import dev.usbharu.hideout.domain.model.ap.Image
|
||||||
import dev.usbharu.hideout.domain.model.ap.Key
|
import dev.usbharu.hideout.domain.model.ap.Key
|
||||||
import dev.usbharu.hideout.domain.model.ap.Person
|
import dev.usbharu.hideout.domain.model.ap.Person
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.Post
|
||||||
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
||||||
import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob
|
import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob
|
||||||
import dev.usbharu.hideout.query.UserQueryService
|
import dev.usbharu.hideout.query.UserQueryService
|
||||||
|
@ -23,12 +24,16 @@ import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.mockito.ArgumentMatchers.anyString
|
import org.mockito.ArgumentMatchers.anyString
|
||||||
import org.mockito.kotlin.*
|
import org.mockito.kotlin.*
|
||||||
import utils.JsonObjectMapper
|
|
||||||
import utils.JsonObjectMapper.objectMapper
|
import utils.JsonObjectMapper.objectMapper
|
||||||
import utils.TestTransaction
|
import utils.TestTransaction
|
||||||
|
import java.net.URL
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
class APReceiveFollowServiceImplTest {
|
class APReceiveFollowServiceImplTest {
|
||||||
|
|
||||||
|
val userBuilder = User.UserBuilder(CharacterLimit(), ApplicationConfig(URL("https://example.com")))
|
||||||
|
val postBuilder = Post.PostBuilder(CharacterLimit())
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `receiveFollow フォロー受付処理`() = runTest {
|
fun `receiveFollow フォロー受付処理`() = runTest {
|
||||||
val jobQueueParentService = mock<JobQueueParentService> {
|
val jobQueueParentService = mock<JobQueueParentService> {
|
||||||
|
@ -80,7 +85,6 @@ class APReceiveFollowServiceImplTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `receiveFollowJob フォロー受付処理のJob`() = runTest {
|
fun `receiveFollowJob フォロー受付処理のJob`() = runTest {
|
||||||
Config.configData = ConfigData(objectMapper = JsonObjectMapper.objectMapper)
|
|
||||||
val person = Person(
|
val person = Person(
|
||||||
type = emptyList(),
|
type = emptyList(),
|
||||||
name = "follower",
|
name = "follower",
|
||||||
|
@ -112,7 +116,7 @@ class APReceiveFollowServiceImplTest {
|
||||||
}
|
}
|
||||||
val userQueryService = mock<UserQueryService> {
|
val userQueryService = mock<UserQueryService> {
|
||||||
onBlocking { findByUrl(eq("https://example.com")) } doReturn
|
onBlocking { findByUrl(eq("https://example.com")) } doReturn
|
||||||
User.of(
|
userBuilder.of(
|
||||||
id = 1L,
|
id = 1L,
|
||||||
name = "test",
|
name = "test",
|
||||||
domain = "example.com",
|
domain = "example.com",
|
||||||
|
@ -122,11 +126,13 @@ class APReceiveFollowServiceImplTest {
|
||||||
outbox = "https://example.com/outbox",
|
outbox = "https://example.com/outbox",
|
||||||
url = "https://example.com",
|
url = "https://example.com",
|
||||||
publicKey = "",
|
publicKey = "",
|
||||||
|
password = "a",
|
||||||
|
privateKey = "a",
|
||||||
createdAt = Instant.now(),
|
createdAt = Instant.now(),
|
||||||
keyId = "a"
|
keyId = "a"
|
||||||
)
|
)
|
||||||
onBlocking { findByUrl(eq("https://follower.example.com")) } doReturn
|
onBlocking { findByUrl(eq("https://follower.example.com")) } doReturn
|
||||||
User.of(
|
userBuilder.of(
|
||||||
id = 2L,
|
id = 2L,
|
||||||
name = "follower",
|
name = "follower",
|
||||||
domain = "follower.example.com",
|
domain = "follower.example.com",
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package dev.usbharu.hideout.service.ap.resource
|
package dev.usbharu.hideout.service.ap.resource
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.config.ApplicationConfig
|
||||||
|
import dev.usbharu.hideout.config.CharacterLimit
|
||||||
import dev.usbharu.hideout.domain.model.ap.Object
|
import dev.usbharu.hideout.domain.model.ap.Object
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.Post
|
||||||
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
||||||
import dev.usbharu.hideout.repository.UserRepository
|
import dev.usbharu.hideout.repository.UserRepository
|
||||||
import io.ktor.client.*
|
import io.ktor.client.*
|
||||||
|
@ -16,6 +19,7 @@ import org.mockito.kotlin.any
|
||||||
import org.mockito.kotlin.doReturn
|
import org.mockito.kotlin.doReturn
|
||||||
import org.mockito.kotlin.mock
|
import org.mockito.kotlin.mock
|
||||||
import org.mockito.kotlin.whenever
|
import org.mockito.kotlin.whenever
|
||||||
|
import java.net.URL
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@ -23,6 +27,9 @@ import kotlin.test.assertEquals
|
||||||
@Disabled
|
@Disabled
|
||||||
class APResourceResolveServiceImplTest {
|
class APResourceResolveServiceImplTest {
|
||||||
|
|
||||||
|
val userBuilder = User.UserBuilder(CharacterLimit(), ApplicationConfig(URL("https://example.com")))
|
||||||
|
val postBuilder = Post.PostBuilder(CharacterLimit())
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `単純な一回のリクエスト`() = runTest {
|
fun `単純な一回のリクエスト`() = runTest {
|
||||||
|
|
||||||
|
@ -36,7 +43,7 @@ class APResourceResolveServiceImplTest {
|
||||||
val userRepository = mock<UserRepository>()
|
val userRepository = mock<UserRepository>()
|
||||||
|
|
||||||
whenever(userRepository.findById(any())).doReturn(
|
whenever(userRepository.findById(any())).doReturn(
|
||||||
User.of(
|
userBuilder.of(
|
||||||
2L,
|
2L,
|
||||||
"follower",
|
"follower",
|
||||||
"follower.example.com",
|
"follower.example.com",
|
||||||
|
@ -72,7 +79,7 @@ class APResourceResolveServiceImplTest {
|
||||||
val userRepository = mock<UserRepository>()
|
val userRepository = mock<UserRepository>()
|
||||||
|
|
||||||
whenever(userRepository.findById(any())).doReturn(
|
whenever(userRepository.findById(any())).doReturn(
|
||||||
User.of(
|
userBuilder.of(
|
||||||
2L,
|
2L,
|
||||||
"follower",
|
"follower",
|
||||||
"follower.example.com",
|
"follower.example.com",
|
||||||
|
@ -111,7 +118,7 @@ class APResourceResolveServiceImplTest {
|
||||||
val userRepository = mock<UserRepository>()
|
val userRepository = mock<UserRepository>()
|
||||||
|
|
||||||
whenever(userRepository.findById(any())).doReturn(
|
whenever(userRepository.findById(any())).doReturn(
|
||||||
User.of(
|
userBuilder.of(
|
||||||
2L,
|
2L,
|
||||||
"follower",
|
"follower",
|
||||||
"follower.example.com",
|
"follower.example.com",
|
||||||
|
@ -161,7 +168,7 @@ class APResourceResolveServiceImplTest {
|
||||||
val userRepository = mock<UserRepository>()
|
val userRepository = mock<UserRepository>()
|
||||||
|
|
||||||
whenever(userRepository.findById(any())).doReturn(
|
whenever(userRepository.findById(any())).doReturn(
|
||||||
User.of(
|
userBuilder.of(
|
||||||
2L,
|
2L,
|
||||||
"follower",
|
"follower",
|
||||||
"follower.example.com",
|
"follower.example.com",
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
|
|
||||||
package dev.usbharu.hideout.service.user
|
package dev.usbharu.hideout.service.user
|
||||||
|
|
||||||
import dev.usbharu.hideout.config.Config
|
import dev.usbharu.hideout.config.ApplicationConfig
|
||||||
import dev.usbharu.hideout.config.ConfigData
|
import dev.usbharu.hideout.config.CharacterLimit
|
||||||
import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto
|
import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto
|
||||||
import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto
|
import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.Post
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
||||||
import dev.usbharu.hideout.repository.UserRepository
|
import dev.usbharu.hideout.repository.UserRepository
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
|
@ -13,14 +15,17 @@ import org.junit.jupiter.api.Test
|
||||||
import org.mockito.ArgumentMatchers.anyString
|
import org.mockito.ArgumentMatchers.anyString
|
||||||
import org.mockito.kotlin.*
|
import org.mockito.kotlin.*
|
||||||
import utils.TestApplicationConfig.testApplicationConfig
|
import utils.TestApplicationConfig.testApplicationConfig
|
||||||
|
import java.net.URL
|
||||||
import java.security.KeyPairGenerator
|
import java.security.KeyPairGenerator
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
|
|
||||||
class UserServiceTest {
|
class UserServiceTest {
|
||||||
|
val userBuilder = User.UserBuilder(CharacterLimit(), ApplicationConfig(URL("https://example.com")))
|
||||||
|
val postBuilder = Post.PostBuilder(CharacterLimit())
|
||||||
@Test
|
@Test
|
||||||
fun `createLocalUser ローカルユーザーを作成できる`() = runTest {
|
fun `createLocalUser ローカルユーザーを作成できる`() = runTest {
|
||||||
Config.configData = ConfigData(domain = "example.com", url = "https://example.com")
|
|
||||||
val userRepository = mock<UserRepository> {
|
val userRepository = mock<UserRepository> {
|
||||||
onBlocking { nextId() } doReturn 110001L
|
onBlocking { nextId() } doReturn 110001L
|
||||||
}
|
}
|
||||||
|
@ -30,7 +35,15 @@ class UserServiceTest {
|
||||||
onBlocking { generateKeyPair() } doReturn generateKeyPair
|
onBlocking { generateKeyPair() } doReturn generateKeyPair
|
||||||
}
|
}
|
||||||
val userService =
|
val userService =
|
||||||
UserServiceImpl(userRepository, userAuthService, mock(), mock(), mock(), testApplicationConfig)
|
UserServiceImpl(
|
||||||
|
userRepository,
|
||||||
|
userAuthService,
|
||||||
|
mock(),
|
||||||
|
mock(),
|
||||||
|
mock(),
|
||||||
|
userBuilder,
|
||||||
|
testApplicationConfig,
|
||||||
|
)
|
||||||
userService.createLocalUser(UserCreateDto("test", "testUser", "XXXXXXXXXXXXX", "test"))
|
userService.createLocalUser(UserCreateDto("test", "testUser", "XXXXXXXXXXXXX", "test"))
|
||||||
verify(userRepository, times(1)).save(any())
|
verify(userRepository, times(1)).save(any())
|
||||||
argumentCaptor<dev.usbharu.hideout.domain.model.hideout.entity.User> {
|
argumentCaptor<dev.usbharu.hideout.domain.model.hideout.entity.User> {
|
||||||
|
@ -51,20 +64,20 @@ class UserServiceTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `createRemoteUser リモートユーザーを作成できる`() = runTest {
|
fun `createRemoteUser リモートユーザーを作成できる`() = runTest {
|
||||||
Config.configData = ConfigData(domain = "remote.example.com", url = "https://remote.example.com")
|
|
||||||
|
|
||||||
val userRepository = mock<UserRepository> {
|
val userRepository = mock<UserRepository> {
|
||||||
onBlocking { nextId() } doReturn 113345L
|
onBlocking { nextId() } doReturn 113345L
|
||||||
}
|
}
|
||||||
val userService = UserServiceImpl(userRepository, mock(), mock(), mock(), mock(), testApplicationConfig)
|
val userService =
|
||||||
|
UserServiceImpl(userRepository, mock(), mock(), mock(), mock(), userBuilder, testApplicationConfig)
|
||||||
val user = RemoteUserCreateDto(
|
val user = RemoteUserCreateDto(
|
||||||
name = "test",
|
name = "test",
|
||||||
domain = "example.com",
|
domain = "remote.example.com",
|
||||||
screenName = "testUser",
|
screenName = "testUser",
|
||||||
description = "test user",
|
description = "test user",
|
||||||
inbox = "https://example.com/inbox",
|
inbox = "https://remote.example.com/inbox",
|
||||||
outbox = "https://example.com/outbox",
|
outbox = "https://remote.example.com/outbox",
|
||||||
url = "https://example.com",
|
url = "https://remote.example.com",
|
||||||
publicKey = "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----",
|
publicKey = "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----",
|
||||||
keyId = "a",
|
keyId = "a",
|
||||||
following = "",
|
following = "",
|
||||||
|
@ -79,10 +92,10 @@ class UserServiceTest {
|
||||||
assertEquals("test user", firstValue.description)
|
assertEquals("test user", firstValue.description)
|
||||||
assertNull(firstValue.password)
|
assertNull(firstValue.password)
|
||||||
assertEquals(113345L, firstValue.id)
|
assertEquals(113345L, firstValue.id)
|
||||||
assertEquals("https://example.com", firstValue.url)
|
assertEquals("https://remote.example.com", firstValue.url)
|
||||||
assertEquals("example.com", firstValue.domain)
|
assertEquals("remote.example.com", firstValue.domain)
|
||||||
assertEquals("https://example.com/inbox", firstValue.inbox)
|
assertEquals("https://remote.example.com/inbox", firstValue.inbox)
|
||||||
assertEquals("https://example.com/outbox", firstValue.outbox)
|
assertEquals("https://remote.example.com/outbox", firstValue.outbox)
|
||||||
assertEquals("-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----", firstValue.publicKey)
|
assertEquals("-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----", firstValue.publicKey)
|
||||||
assertNull(firstValue.privateKey)
|
assertNull(firstValue.privateKey)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue