From 1f784f339a32d968995a81c042835f58663c528f Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 23 Oct 2023 12:17:48 +0900 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20Post=E3=82=92=E3=83=93=E3=83=AB?= =?UTF-8?q?=E3=83=80=E3=83=BC=E3=82=92=E4=BD=BF=E3=81=A3=E3=81=A6=E7=94=9F?= =?UTF-8?q?=E6=88=90=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/config/Config.kt | 47 -------------- .../usbharu/hideout/config/SpringConfig.kt | 33 ++++++++++ .../domain/model/hideout/entity/Post.kt | 61 +++++++++++++++++++ .../hideout/service/ap/APNoteService.kt | 3 +- .../hideout/service/post/PostServiceImpl.kt | 5 +- 5 files changed, 99 insertions(+), 50 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/config/Config.kt b/src/main/kotlin/dev/usbharu/hideout/config/Config.kt index 1623ff25..45023914 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/Config.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/Config.kt @@ -15,50 +15,3 @@ data class ConfigData( 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 - ) -} diff --git a/src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt index 18ee3845..237b2c6c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt @@ -28,6 +28,7 @@ class SpringConfig { } } + @ConfigurationProperties("hideout") data class ApplicationConfig( val url: URL @@ -43,3 +44,35 @@ data class StorageConfig( val accessKey: 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 + ) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/Post.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/Post.kt index afe45261..d500c2cd 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/Post.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/Post.kt @@ -1,6 +1,8 @@ package dev.usbharu.hideout.domain.model.hideout.entity +import dev.usbharu.hideout.config.CharacterLimit import dev.usbharu.hideout.config.Config +import org.springframework.stereotype.Component data class Post private constructor( val id: Long, @@ -18,6 +20,7 @@ data class Post private constructor( ) { companion object { @Suppress("FunctionMinLength", "LongParameterList") + @Deprecated("Static builder is deprecated") fun of( id: Long, userId: Long, @@ -74,4 +77,62 @@ data class Post private constructor( ) } } + + @Component + class PostBuilder(private val characterLimit: CharacterLimit) { + @Suppress("FunctionMinLength", "LongParameterList") + fun of( + id: Long, + userId: Long, + overview: String? = null, + text: String, + createdAt: Long, + visibility: Visibility, + url: String, + repostId: Long? = null, + replyId: Long? = null, + sensitive: Boolean = false, + apId: String = url, + mediaIds: List = emptyList() + ): Post { + require(id >= 0) { "id must be greater than or equal to 0." } + + require(userId >= 0) { "userId must be greater than or equal to 0." } + + val limitedOverview = if ((overview?.length ?: 0) >= characterLimit.post.overview) { + overview?.substring(0, characterLimit.post.overview) + } else { + overview + } + + val limitedText = if (text.length >= characterLimit.post.text) { + text.substring(0, characterLimit.post.text) + } else { + text + } + + require(url.isNotBlank()) { "url must contain non-blank characters" } + require(url.length <= characterLimit.general.url) { + "url must not exceed ${characterLimit.general.url} characters." + } + + require((repostId ?: 0) >= 0) { "repostId must be greater then or equal to 0." } + require((replyId ?: 0) >= 0) { "replyId must be greater then or equal to 0." } + + return Post( + id = id, + userId = userId, + overview = limitedOverview, + text = limitedText, + createdAt = createdAt, + visibility = visibility, + url = url, + repostId = repostId, + replyId = replyId, + sensitive = sensitive, + apId = apId, + mediaIds = mediaIds + ) + } + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt index 8a7b1a95..26a6306b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt @@ -69,6 +69,7 @@ class APNoteServiceImpl( private val postService: PostService, private val apResourceResolveService: APResourceResolveService, private val apRequestService: APRequestService, + private val postBuilder: Post.PostBuilder, private val transaction: Transaction ) : APNoteService, PostCreateInterceptor { @@ -224,7 +225,7 @@ class APNoteServiceImpl( // TODO: リモートのメディア処理を追加 postService.createRemote( - Post.of( + postBuilder.of( id = postRepository.generateId(), userId = person.second.id, text = note.content.orEmpty(), diff --git a/src/main/kotlin/dev/usbharu/hideout/service/post/PostServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/post/PostServiceImpl.kt index ac5e54c6..c98ee233 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/post/PostServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/post/PostServiceImpl.kt @@ -16,7 +16,8 @@ class PostServiceImpl( private val postRepository: PostRepository, private val userRepository: UserRepository, private val timelineService: TimelineService, - private val postQueryService: PostQueryService + private val postQueryService: PostQueryService, + private val postBuilder: Post.PostBuilder ) : PostService { private val interceptors = Collections.synchronizedList(mutableListOf()) @@ -45,7 +46,7 @@ class PostServiceImpl( private suspend fun internalCreate(post: PostCreateDto, isLocal: Boolean): Post { val user = userRepository.findById(post.userId) ?: throw UserNotFoundException("${post.userId} was not found") val id = postRepository.generateId() - val createPost = Post.of( + val createPost = postBuilder.of( id = id, userId = post.userId, overview = post.overview, From 95c7565b78405eb72dfcedd827b3b17742ccfffd Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 23 Oct 2023 12:35:48 +0900 Subject: [PATCH 02/11] =?UTF-8?q?feat:=20UserBUilder=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/model/hideout/entity/User.kt | 120 ++++++++++++++++++ .../hideout/query/FollowerQueryServiceImpl.kt | 10 +- .../hideout/service/user/UserServiceImpl.kt | 5 +- 3 files changed, 128 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt index d79d617b..38eb81a2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt @@ -1,7 +1,10 @@ package dev.usbharu.hideout.domain.model.hideout.entity +import dev.usbharu.hideout.config.ApplicationConfig +import dev.usbharu.hideout.config.CharacterLimit import dev.usbharu.hideout.config.Config import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component import java.time.Instant data class User private constructor( @@ -145,4 +148,121 @@ data class User private constructor( ) } } + + @Component + class UserBuilder(private val characterLimit: CharacterLimit, private val applicationConfig: ApplicationConfig) { + private val logger = LoggerFactory.getLogger(UserBuilder::class.java) + + @Suppress("LongParameterList", "FunctionMinLength", "LongMethod") + fun of( + id: Long, + name: String, + domain: String, + screenName: String, + description: String, + password: String? = null, + inbox: String, + outbox: String, + url: String, + publicKey: String, + privateKey: String? = null, + createdAt: Instant, + keyId: String, + following: String? = null, + followers: String? = null + ): User { + // idは0未満ではいけない + require(id >= 0) { "id must be greater than or equal to 0." } + + // nameは空文字以外を含める必要がある + require(name.isNotBlank()) { "name must contain non-blank characters." } + + // nameは指定された長さ以下である必要がある + val limitedName = if (name.length >= characterLimit.account.id) { + logger.warn("name must not exceed ${characterLimit.account.id} characters.") + name.substring(0, characterLimit.account.id) + } else { + name + } + + // domainは空文字以外を含める必要がある + require(domain.isNotBlank()) { "domain must contain non-blank characters." } + + // domainは指定された長さ以下である必要がある + require(domain.length <= characterLimit.general.domain) { + "domain must not exceed ${characterLimit.general.domain} characters." + } + + // screenNameは空文字以外を含める必要がある + require(screenName.isNotBlank()) { "screenName must contain non-blank characters." } + + // screenNameは指定された長さ以下である必要がある + val limitedScreenName = if (screenName.length >= characterLimit.account.name) { + logger.warn("screenName must not exceed ${characterLimit.account.name} characters.") + screenName.substring(0, characterLimit.account.name) + } else { + screenName + } + + // descriptionは指定された長さ以下である必要がある + val limitedDescription = if (description.length >= characterLimit.account.description) { + logger.warn("description must not exceed ${characterLimit.account.description} characters.") + description.substring(0, characterLimit.account.description) + } else { + description + } + + // ローカルユーザーはpasswordとprivateKeyをnullにしてはいけない + if (domain == applicationConfig.url.host) { + requireNotNull(password) { "password and privateKey must not be null for local users." } + requireNotNull(privateKey) { "password and privateKey must not be null for local users." } + } + + // urlは空文字以外を含める必要がある + require(url.isNotBlank()) { "url must contain non-blank characters." } + + // urlは指定された長さ以下である必要がある + require(url.length <= characterLimit.general.url) { + "url must not exceed ${characterLimit.general.url} characters." + } + + // inboxは空文字以外を含める必要がある + require(inbox.isNotBlank()) { "inbox must contain non-blank characters." } + + // inboxは指定された長さ以下である必要がある + require(inbox.length <= characterLimit.general.url) { + "inbox must not exceed ${characterLimit.general.url} characters." + } + + // outboxは空文字以外を含める必要がある + require(outbox.isNotBlank()) { "outbox must contain non-blank characters." } + + // outboxは指定された長さ以下である必要がある + require(outbox.length <= characterLimit.general.url) { + "outbox must not exceed ${characterLimit.general.url} characters." + } + + require(keyId.isNotBlank()) { + "keyId must contain non-blank characters." + } + + return User( + id = id, + name = limitedName, + domain = domain, + screenName = limitedScreenName, + description = limitedDescription, + password = password, + inbox = inbox, + outbox = outbox, + url = url, + publicKey = publicKey, + privateKey = privateKey, + createdAt = createdAt, + keyId = keyId, + followers = followers, + following = following + ) + } + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/query/FollowerQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/FollowerQueryServiceImpl.kt index 10be4068..75d27e7b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/FollowerQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/FollowerQueryServiceImpl.kt @@ -9,7 +9,7 @@ import org.springframework.stereotype.Repository import java.time.Instant @Repository -class FollowerQueryServiceImpl : FollowerQueryService { +class FollowerQueryServiceImpl(private val userBuilder: User.UserBuilder) : FollowerQueryService { override suspend fun findFollowersById(id: Long): List { val followers = Users.alias("FOLLOWERS") return Users.innerJoin( @@ -41,7 +41,7 @@ class FollowerQueryServiceImpl : FollowerQueryService { ) .select { Users.id eq id } .map { - User.of( + userBuilder.of( id = it[followers[Users.id]], name = it[followers[Users.name]], domain = it[followers[Users.domain]], @@ -92,7 +92,7 @@ class FollowerQueryServiceImpl : FollowerQueryService { ) .select { Users.name eq name and (Users.domain eq domain) } .map { - User.of( + userBuilder.of( id = it[followers[Users.id]], name = it[followers[Users.name]], domain = it[followers[Users.domain]], @@ -143,7 +143,7 @@ class FollowerQueryServiceImpl : FollowerQueryService { ) .select { followers[Users.id] eq id } .map { - User.of( + userBuilder.of( id = it[followers[Users.id]], name = it[followers[Users.name]], domain = it[followers[Users.domain]], @@ -194,7 +194,7 @@ class FollowerQueryServiceImpl : FollowerQueryService { ) .select { followers[Users.name] eq name and (followers[Users.domain] eq domain) } .map { - User.of( + userBuilder.of( id = it[followers[Users.id]], name = it[followers[Users.name]], domain = it[followers[Users.domain]], diff --git a/src/main/kotlin/dev/usbharu/hideout/service/user/UserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/user/UserServiceImpl.kt index bb349ff3..6688ce48 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/user/UserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/user/UserServiceImpl.kt @@ -21,6 +21,7 @@ class UserServiceImpl( private val apSendFollowService: APSendFollowService, private val userQueryService: UserQueryService, private val followerQueryService: FollowerQueryService, + private val userBuilder: User.UserBuilder, private val applicationConfig: ApplicationConfig ) : UserService { @@ -35,7 +36,7 @@ class UserServiceImpl( val hashedPassword = userAuthService.hash(user.password) val keyPair = userAuthService.generateKeyPair() val userUrl = "${applicationConfig.url}/users/${user.name}" - val userEntity = User.of( + val userEntity = userBuilder.of( id = nextId, name = user.name, domain = applicationConfig.url.host, @@ -57,7 +58,7 @@ class UserServiceImpl( override suspend fun createRemoteUser(user: RemoteUserCreateDto): User { val nextId = userRepository.nextId() - val userEntity = User.of( + val userEntity = userBuilder.of( id = nextId, name = user.name, domain = user.domain, From 3a3318a25fb426f81bffde152e261ef8ab4813c5 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 23 Oct 2023 12:49:08 +0900 Subject: [PATCH 03/11] =?UTF-8?q?feat:=20DB=E3=81=AE=E6=96=87=E5=AD=97?= =?UTF-8?q?=E6=95=B0=E5=88=B6=E9=99=90=E3=82=92=E3=83=8F=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/repository/UserRepositoryImpl.kt | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt index a6955a5d..85643afe 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt @@ -1,6 +1,5 @@ package dev.usbharu.hideout.repository -import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.service.core.IdGenerateService import org.jetbrains.exposed.dao.id.LongIdTable @@ -78,26 +77,26 @@ class UserRepositoryImpl(private val idGenerateService: IdGenerateService) : object Users : Table("users") { val id: Column = long("id") - val name: Column = varchar("name", length = Config.configData.characterLimit.account.id) - val domain: Column = varchar("domain", length = Config.configData.characterLimit.general.domain) - val screenName: Column = varchar("screen_name", length = Config.configData.characterLimit.account.name) + val name: Column = varchar("name", length = 300) + val domain: Column = varchar("domain", length = 1000) + val screenName: Column = varchar("screen_name", length = 300) val description: Column = varchar( "description", - length = Config.configData.characterLimit.account.description + length = 10000 ) val password: Column = varchar("password", length = 255).nullable() - val inbox: Column = varchar("inbox", length = Config.configData.characterLimit.general.url).uniqueIndex() - val outbox: Column = varchar("outbox", length = Config.configData.characterLimit.general.url).uniqueIndex() - val url: Column = varchar("url", length = Config.configData.characterLimit.general.url).uniqueIndex() - val publicKey: Column = varchar("public_key", length = Config.configData.characterLimit.general.publicKey) + val inbox: Column = varchar("inbox", length = 1000).uniqueIndex() + val outbox: Column = varchar("outbox", length = 1000).uniqueIndex() + val url: Column = varchar("url", length = 1000).uniqueIndex() + val publicKey: Column = varchar("public_key", length = 10000) val privateKey: Column = varchar( "private_key", - length = Config.configData.characterLimit.general.privateKey + length = 10000 ).nullable() val createdAt: Column = long("created_at") - val keyId = varchar("key_id", length = Config.configData.characterLimit.general.url) - val following = varchar("following", length = Config.configData.characterLimit.general.url).nullable() - val followers = varchar("followers", length = Config.configData.characterLimit.general.url).nullable() + val keyId = varchar("key_id", length = 1000) + val following = varchar("following", length = 1000).nullable() + val followers = varchar("followers", length = 1000).nullable() override val primaryKey: PrimaryKey = PrimaryKey(id) From 830206b43ab5eb7877bcb3bf11cc55751407fcbd Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 23 Oct 2023 12:50:25 +0900 Subject: [PATCH 04/11] =?UTF-8?q?feat:=20=E4=B8=8D=E8=A6=81=E3=81=AA?= =?UTF-8?q?=E3=82=B3=E3=83=B3=E3=83=95=E3=82=A3=E3=82=B0=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/config/Config.kt | 4 ---- .../dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt | 3 +-- .../hideout/service/ap/APReceiveFollowServiceImplTest.kt | 3 +-- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/config/Config.kt b/src/main/kotlin/dev/usbharu/hideout/config/Config.kt index 45023914..011754f1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/Config.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/Config.kt @@ -1,8 +1,5 @@ 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() @@ -12,6 +9,5 @@ object Config { data class ConfigData( val url: String = "", val domain: String = url.substringAfter("://").substringBeforeLast(":"), - val objectMapper: ObjectMapper = jacksonObjectMapper(), val characterLimit: CharacterLimit = CharacterLimit() ) diff --git a/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt index 2543c8e9..1c007f3e 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt @@ -23,7 +23,6 @@ import org.junit.jupiter.api.Test import org.mockito.Mockito.anyLong import org.mockito.Mockito.eq import org.mockito.kotlin.* -import utils.JsonObjectMapper import utils.JsonObjectMapper.objectMapper import utils.TestApplicationConfig.testApplicationConfig import java.time.Instant @@ -123,7 +122,7 @@ class APNoteServiceImplTest { val mediaQueryService = mock { onBlocking { findByPostId(anyLong()) } doReturn emptyList() } - Config.configData = ConfigData(objectMapper = JsonObjectMapper.objectMapper) + Config.configData = ConfigData() val httpClient = HttpClient( MockEngine { httpRequestData -> assertEquals("https://follower.example.com/inbox", httpRequestData.url.toString()) diff --git a/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt index d1d51fa7..e786f016 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt @@ -23,7 +23,6 @@ import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.* -import utils.JsonObjectMapper import utils.JsonObjectMapper.objectMapper import utils.TestTransaction import java.time.Instant @@ -80,7 +79,7 @@ class APReceiveFollowServiceImplTest { @Test fun `receiveFollowJob フォロー受付処理のJob`() = runTest { - Config.configData = ConfigData(objectMapper = JsonObjectMapper.objectMapper) + Config.configData = ConfigData() val person = Person( type = emptyList(), name = "follower", From 4e27f2e68bca9f97446d7978e2af158236e22860 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 23 Oct 2023 13:15:28 +0900 Subject: [PATCH 05/11] =?UTF-8?q?feat:=20=E3=82=AF=E3=82=A8=E3=83=AA?= =?UTF-8?q?=E5=AE=9F=E8=A1=8C=E7=B5=90=E6=9E=9C=E3=81=A8=E3=81=AE=E3=83=9E?= =?UTF-8?q?=E3=83=83=E3=83=94=E3=83=B3=E3=82=B0=E3=82=92=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=81=AB=E5=88=87=E3=82=8A=E5=87=BA=E3=81=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/query/PostQueryServiceImpl.kt | 15 +++++++---- .../query/activitypub/NoteQueryServiceImpl.kt | 5 ++-- .../hideout/repository/PostQueryMapper.kt | 17 +++++++++++++ .../hideout/repository/PostRepositoryImpl.kt | 9 +++++-- .../hideout/repository/PostResultRowMapper.kt | 25 +++++++++++++++++++ .../usbharu/hideout/repository/QueryMapper.kt | 7 ++++++ .../hideout/repository/ResultRowMapper.kt | 7 ++++++ 7 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/repository/PostQueryMapper.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/repository/PostResultRowMapper.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/repository/QueryMapper.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/repository/ResultRowMapper.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt index dc3d3d9a..718cae24 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt @@ -4,27 +4,32 @@ import dev.usbharu.hideout.domain.model.hideout.entity.Post import dev.usbharu.hideout.exception.FailedToGetResourcesException import dev.usbharu.hideout.repository.Posts 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 org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository @Repository -class PostQueryServiceImpl : PostQueryService { +class PostQueryServiceImpl( + private val postResultRowMapper: ResultRowMapper, + private val postQueryMapper: QueryMapper +) : PostQueryService { override suspend fun findById(id: Long): Post = Posts.leftJoin(PostsMedia) .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 = Posts.leftJoin(PostsMedia) .select { Posts.url eq url } - .toPost() + .let(postQueryMapper::map) .singleOr { FailedToGetResourcesException("url: $url is duplicate or does not exist.", it) } override suspend fun findByApId(string: String): Post = Posts.leftJoin(PostsMedia) .select { Posts.apId eq string } - .toPost() + .let(postQueryMapper::map) .singleOr { FailedToGetResourcesException("apId: $string is duplicate or does not exist.", it) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt index 93992395..26f5d23c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt @@ -13,14 +13,15 @@ import org.springframework.stereotype.Repository import java.time.Instant @Repository -class NoteQueryServiceImpl(private val postRepository: PostRepository) : NoteQueryService { +class NoteQueryServiceImpl(private val postRepository: PostRepository, private val postQueryMapper: QueryMapper) : + NoteQueryService { override suspend fun findById(id: Long): Pair { return Posts .leftJoin(Users) .leftJoin(PostsMedia) .leftJoin(Media) .select { Posts.id eq id } - .let { it.toNote() to it.toPost().first() } + .let { it.toNote() to postQueryMapper.map(it).first() } } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/PostQueryMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/PostQueryMapper.kt new file mode 100644 index 00000000..158adb7e --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/repository/PostQueryMapper.kt @@ -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) : QueryMapper { + override fun map(query: Query): List { + return query.groupBy { it[Posts.id] } + .map { it.value } + .map { + it.first().let(postResultRowMapper::map)!! + .copy(mediaIds = it.mapNotNull { it.getOrNull(PostsMedia.mediaId) }) + } + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt index 9100422a..c13c90a7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt @@ -9,7 +9,10 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.springframework.stereotype.Repository @Repository -class PostRepositoryImpl(private val idGenerateService: IdGenerateService) : PostRepository { +class PostRepositoryImpl( + private val idGenerateService: IdGenerateService, + private val postQueryMapper: QueryMapper +) : PostRepository { override suspend fun generateId(): Long = idGenerateService.generateId() @@ -65,7 +68,7 @@ class PostRepositoryImpl(private val idGenerateService: IdGenerateService) : Pos override suspend fun findById(id: Long): Post = Posts.innerJoin(PostsMedia, onColumn = { Posts.id }, otherColumn = { PostsMedia.postId }) .select { Posts.id eq id } - .toPost() + .let(postQueryMapper::map) .singleOrNull() ?: throw FailedToGetResourcesException("id: $id was not found.") @@ -95,6 +98,7 @@ object PostsMedia : Table() { override val primaryKey = PrimaryKey(postId, mediaId) } +@Deprecated("toPost is depracated") fun ResultRow.toPost(): Post { return Post.of( id = this[Posts.id], @@ -111,6 +115,7 @@ fun ResultRow.toPost(): Post { ) } +@Deprecated("toPost is deprecated") fun Query.toPost(): List { return this.groupBy { it[Posts.id] } .map { it.value } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/PostResultRowMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/PostResultRowMapper.kt new file mode 100644 index 00000000..7949e401 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/repository/PostResultRowMapper.kt @@ -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 { + 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], + ) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/QueryMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/QueryMapper.kt new file mode 100644 index 00000000..b5b5fdad --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/repository/QueryMapper.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.repository + +import org.jetbrains.exposed.sql.Query + +interface QueryMapper { + fun map(query: Query): List +} diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/ResultRowMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/ResultRowMapper.kt new file mode 100644 index 00000000..2a338e98 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/repository/ResultRowMapper.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.repository + +import org.jetbrains.exposed.sql.ResultRow + +interface ResultRowMapper { + fun map(resultRow: ResultRow): T? +} From 0403ae969f2a6829464f2a09286aabe14b16c6bb Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 23 Oct 2023 13:16:07 +0900 Subject: [PATCH 06/11] =?UTF-8?q?feat:=20=E4=B8=8D=E8=A6=81=E3=81=AB?= =?UTF-8?q?=E3=81=AA=E3=81=A3=E3=81=9F=E3=83=9E=E3=83=83=E3=83=94=E3=83=B3?= =?UTF-8?q?=E3=82=B0=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/repository/PostRepositoryImpl.kt | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt index c13c90a7..d0a8ee96 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt @@ -1,7 +1,6 @@ package dev.usbharu.hideout.repository 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.service.core.IdGenerateService import org.jetbrains.exposed.sql.* @@ -97,27 +96,3 @@ object PostsMedia : Table() { val mediaId = long("media_id").references(Media.id, ReferenceOption.CASCADE, ReferenceOption.CASCADE) override val primaryKey = PrimaryKey(postId, mediaId) } - -@Deprecated("toPost is depracated") -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], - ) -} - -@Deprecated("toPost is deprecated") -fun Query.toPost(): List { - return this.groupBy { it[Posts.id] } - .map { it.value } - .map { it.first().toPost().copy(mediaIds = it.mapNotNull { it.getOrNull(PostsMedia.mediaId) }) } -} From a6818ca09070e30ef280b6e753f2a4b39046b29b Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 23 Oct 2023 13:28:28 +0900 Subject: [PATCH 07/11] =?UTF-8?q?feat:=20User=E3=81=AE=E3=83=9E=E3=83=83?= =?UTF-8?q?=E3=83=94=E3=83=B3=E3=82=B0=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/query/PostQueryServiceImpl.kt | 2 +- .../hideout/query/UserQueryServiceImpl.kt | 24 +++++++++------ .../hideout/repository/PostQueryMapper.kt | 2 +- .../hideout/repository/ResultRowMapper.kt | 2 +- .../hideout/repository/UserQueryMapper.kt | 12 ++++++++ .../hideout/repository/UserRepositoryImpl.kt | 9 +++--- .../hideout/repository/UserResultRowMapper.kt | 29 +++++++++++++++++++ 7 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/repository/UserQueryMapper.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/repository/UserResultRowMapper.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt index 718cae24..c6708dae 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt @@ -19,7 +19,7 @@ class PostQueryServiceImpl( Posts.leftJoin(PostsMedia) .select { Posts.id eq id } .singleOr { FailedToGetResourcesException("id: $id is duplicate or does not exist.", it) } - .let(postResultRowMapper::map)!! + .let(postResultRowMapper::map) override suspend fun findByUrl(url: String): Post = Posts.leftJoin(PostsMedia) diff --git a/src/main/kotlin/dev/usbharu/hideout/query/UserQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/UserQueryServiceImpl.kt index 351a8303..3db693e1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/UserQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/UserQueryServiceImpl.kt @@ -2,8 +2,9 @@ package dev.usbharu.hideout.query import dev.usbharu.hideout.domain.model.hideout.entity.User 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.toUser import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.select @@ -12,17 +13,22 @@ import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository @Repository -class UserQueryServiceImpl : UserQueryService { +class UserQueryServiceImpl( + private val userResultRowMapper: ResultRowMapper, + private val userQueryMapper: QueryMapper +) : UserQueryService { private val logger = LoggerFactory.getLogger(UserQueryServiceImpl::class.java) override suspend fun findAll(limit: Int, offset: Long): List = - 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 } - .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 = Users.select { Users.name eq name }.map { it.toUser() } + override suspend fun findByName(name: String): List = + Users.select { Users.name eq name }.let(userQueryMapper::map) override suspend fun findByNameAndDomain(name: String, domain: String): User = Users @@ -30,17 +36,17 @@ class UserQueryServiceImpl : UserQueryService { .singleOr { FailedToGetResourcesException("name: $name,domain: $domain is duplicate or does not exist.", it) } - .toUser() + .let(userResultRowMapper::map) override suspend fun findByUrl(url: String): User { logger.trace("findByUrl url: $url") return Users.select { Users.url eq url } .singleOr { FailedToGetResourcesException("url: $url is duplicate or does not exist.", it) } - .toUser() + .let(userResultRowMapper::map) } override suspend fun findByIds(ids: List): List = - 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 = 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 { return Users.select { Users.keyId eq keyId } .singleOr { FailedToGetResourcesException("keyId: $keyId is duplicate or does not exist.", it) } - .toUser() + .let(userResultRowMapper::map) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/PostQueryMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/PostQueryMapper.kt index 158adb7e..f71d5492 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/PostQueryMapper.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/PostQueryMapper.kt @@ -10,7 +10,7 @@ class PostQueryMapper(private val postResultRowMapper: ResultRowMapper) : return query.groupBy { it[Posts.id] } .map { it.value } .map { - it.first().let(postResultRowMapper::map)!! + it.first().let(postResultRowMapper::map) .copy(mediaIds = it.mapNotNull { it.getOrNull(PostsMedia.mediaId) }) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/ResultRowMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/ResultRowMapper.kt index 2a338e98..e2ea4b3f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/ResultRowMapper.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/ResultRowMapper.kt @@ -3,5 +3,5 @@ package dev.usbharu.hideout.repository import org.jetbrains.exposed.sql.ResultRow interface ResultRowMapper { - fun map(resultRow: ResultRow): T? + fun map(resultRow: ResultRow): T } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserQueryMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserQueryMapper.kt new file mode 100644 index 00000000..62828e72 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserQueryMapper.kt @@ -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) : QueryMapper { + override fun map(query: Query): List { + return query.map(userResultRowMapper::map) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt index 85643afe..323c70a7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt @@ -9,7 +9,10 @@ import org.springframework.stereotype.Repository import java.time.Instant @Repository -class UserRepositoryImpl(private val idGenerateService: IdGenerateService) : +class UserRepositoryImpl( + private val idGenerateService: IdGenerateService, + private val userResultRowMapper: ResultRowMapper +) : UserRepository { override suspend fun save(user: User): User { @@ -54,9 +57,7 @@ class UserRepositoryImpl(private val idGenerateService: IdGenerateService) : } override suspend fun findById(id: Long): User? { - return Users.select { Users.id eq id }.map { - it.toUser() - }.singleOrNull() + return Users.select { Users.id eq id }.singleOrNull()?.let(userResultRowMapper::map) } override suspend fun deleteFollowRequest(id: Long, follower: Long) { diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserResultRowMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserResultRowMapper.kt new file mode 100644 index 00000000..8470a2f6 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserResultRowMapper.kt @@ -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 { + 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] + ) + } +} From 1b1be8f7b0188d0bb4cf99838c73e4b317684e43 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 23 Oct 2023 13:29:09 +0900 Subject: [PATCH 08/11] =?UTF-8?q?feat:=20=E4=B8=8D=E8=A6=81=E3=81=AB?= =?UTF-8?q?=E3=81=AA=E3=81=A3=E3=81=9F=E3=83=9E=E3=83=83=E3=83=94=E3=83=B3?= =?UTF-8?q?=E3=82=B0=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/repository/UserRepositoryImpl.kt | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt index 323c70a7..0a1a9958 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt @@ -6,7 +6,6 @@ import org.jetbrains.exposed.dao.id.LongIdTable import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.springframework.stereotype.Repository -import java.time.Instant @Repository class UserRepositoryImpl( @@ -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") { val userId: Column = long("user_id").references(Users.id).index() val followerId: Column = long("follower_id").references(Users.id) From 7427030f0090cd0f960f2a10d11158467a0121ba Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 23 Oct 2023 13:32:50 +0900 Subject: [PATCH 09/11] =?UTF-8?q?feat:=20=E4=B8=8D=E8=A6=81=E3=81=AB?= =?UTF-8?q?=E3=81=AA=E3=81=A3=E3=81=9F=E3=82=B3=E3=83=B3=E3=83=95=E3=82=A3?= =?UTF-8?q?=E3=82=B0=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/config/Config.kt | 13 -- .../domain/model/hideout/entity/Post.kt | 60 --------- .../domain/model/hideout/entity/User.kt | 120 ------------------ .../service/ap/APNoteServiceImplTest.kt | 3 +- .../ap/APReceiveFollowServiceImplTest.kt | 3 +- .../hideout/service/user/UserServiceTest.kt | 3 +- 6 files changed, 3 insertions(+), 199 deletions(-) delete mode 100644 src/main/kotlin/dev/usbharu/hideout/config/Config.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/config/Config.kt b/src/main/kotlin/dev/usbharu/hideout/config/Config.kt deleted file mode 100644 index 011754f1..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/config/Config.kt +++ /dev/null @@ -1,13 +0,0 @@ -package dev.usbharu.hideout.config - -@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 characterLimit: CharacterLimit = CharacterLimit() -) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/Post.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/Post.kt index d500c2cd..7bffa75e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/Post.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/Post.kt @@ -1,7 +1,6 @@ package dev.usbharu.hideout.domain.model.hideout.entity import dev.usbharu.hideout.config.CharacterLimit -import dev.usbharu.hideout.config.Config import org.springframework.stereotype.Component data class Post private constructor( @@ -18,65 +17,6 @@ data class Post private constructor( val apId: String = url, val mediaIds: List = emptyList() ) { - companion object { - @Suppress("FunctionMinLength", "LongParameterList") - @Deprecated("Static builder is deprecated") - fun of( - id: Long, - userId: Long, - overview: String? = null, - text: String, - createdAt: Long, - visibility: Visibility, - url: String, - repostId: Long? = null, - replyId: Long? = null, - sensitive: Boolean = false, - apId: String = url, - mediaIds: List = emptyList() - ): Post { - val characterLimit = Config.configData.characterLimit - - require(id >= 0) { "id must be greater than or equal to 0." } - - require(userId >= 0) { "userId must be greater than or equal to 0." } - - val limitedOverview = if ((overview?.length ?: 0) >= characterLimit.post.overview) { - overview?.substring(0, characterLimit.post.overview) - } else { - overview - } - - val limitedText = if (text.length >= characterLimit.post.text) { - text.substring(0, characterLimit.post.text) - } else { - text - } - - require(url.isNotBlank()) { "url must contain non-blank characters" } - require(url.length <= characterLimit.general.url) { - "url must not exceed ${characterLimit.general.url} characters." - } - - require((repostId ?: 0) >= 0) { "repostId must be greater then or equal to 0." } - require((replyId ?: 0) >= 0) { "replyId must be greater then or equal to 0." } - - return Post( - id = id, - userId = userId, - overview = limitedOverview, - text = limitedText, - createdAt = createdAt, - visibility = visibility, - url = url, - repostId = repostId, - replyId = replyId, - sensitive = sensitive, - apId = apId, - mediaIds = mediaIds - ) - } - } @Component class PostBuilder(private val characterLimit: CharacterLimit) { diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt index 38eb81a2..302a3c1e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt @@ -2,7 +2,6 @@ package dev.usbharu.hideout.domain.model.hideout.entity import dev.usbharu.hideout.config.ApplicationConfig import dev.usbharu.hideout.config.CharacterLimit -import dev.usbharu.hideout.config.Config import org.slf4j.LoggerFactory import org.springframework.stereotype.Component import java.time.Instant @@ -30,125 +29,6 @@ data class User private constructor( " privateKey=$privateKey, createdAt=$createdAt, keyId='$keyId', followers=$followers," + " following=$following)" - companion object { - - private val logger = LoggerFactory.getLogger(User::class.java) - - @Suppress("LongParameterList", "FunctionMinLength", "LongMethod") - fun of( - id: Long, - name: String, - domain: String, - screenName: String, - description: String, - password: String? = null, - inbox: String, - outbox: String, - url: String, - publicKey: String, - privateKey: String? = null, - createdAt: Instant, - keyId: String, - following: String? = null, - followers: String? = null - ): User { - val characterLimit = Config.configData.characterLimit - - // idは0未満ではいけない - require(id >= 0) { "id must be greater than or equal to 0." } - - // nameは空文字以外を含める必要がある - require(name.isNotBlank()) { "name must contain non-blank characters." } - - // nameは指定された長さ以下である必要がある - val limitedName = if (name.length >= characterLimit.account.id) { - logger.warn("name must not exceed ${characterLimit.account.id} characters.") - name.substring(0, characterLimit.account.id) - } else { - name - } - - // domainは空文字以外を含める必要がある - require(domain.isNotBlank()) { "domain must contain non-blank characters." } - - // domainは指定された長さ以下である必要がある - require(domain.length <= characterLimit.general.domain) { - "domain must not exceed ${characterLimit.general.domain} characters." - } - - // screenNameは空文字以外を含める必要がある - require(screenName.isNotBlank()) { "screenName must contain non-blank characters." } - - // screenNameは指定された長さ以下である必要がある - val limitedScreenName = if (screenName.length >= characterLimit.account.name) { - logger.warn("screenName must not exceed ${characterLimit.account.name} characters.") - screenName.substring(0, characterLimit.account.name) - } else { - screenName - } - - // descriptionは指定された長さ以下である必要がある - val limitedDescription = if (description.length >= characterLimit.account.description) { - logger.warn("description must not exceed ${characterLimit.account.description} characters.") - description.substring(0, characterLimit.account.description) - } else { - description - } - - // ローカルユーザーはpasswordとprivateKeyをnullにしてはいけない - if (domain == Config.configData.domain) { - requireNotNull(password) { "password and privateKey must not be null for local users." } - requireNotNull(privateKey) { "password and privateKey must not be null for local users." } - } - - // urlは空文字以外を含める必要がある - require(url.isNotBlank()) { "url must contain non-blank characters." } - - // urlは指定された長さ以下である必要がある - require(url.length <= characterLimit.general.url) { - "url must not exceed ${characterLimit.general.url} characters." - } - - // inboxは空文字以外を含める必要がある - require(inbox.isNotBlank()) { "inbox must contain non-blank characters." } - - // inboxは指定された長さ以下である必要がある - require(inbox.length <= characterLimit.general.url) { - "inbox must not exceed ${characterLimit.general.url} characters." - } - - // outboxは空文字以外を含める必要がある - require(outbox.isNotBlank()) { "outbox must contain non-blank characters." } - - // outboxは指定された長さ以下である必要がある - require(outbox.length <= characterLimit.general.url) { - "outbox must not exceed ${characterLimit.general.url} characters." - } - - require(keyId.isNotBlank()) { - "keyId must contain non-blank characters." - } - - return User( - id = id, - name = limitedName, - domain = domain, - screenName = limitedScreenName, - description = limitedDescription, - password = password, - inbox = inbox, - outbox = outbox, - url = url, - publicKey = publicKey, - privateKey = privateKey, - createdAt = createdAt, - keyId = keyId, - followers = followers, - following = following - ) - } - } - @Component class UserBuilder(private val characterLimit: CharacterLimit, private val applicationConfig: ApplicationConfig) { private val logger = LoggerFactory.getLogger(UserBuilder::class.java) diff --git a/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt index 1c007f3e..bc9ab9c6 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt @@ -3,8 +3,6 @@ package dev.usbharu.hideout.service.ap -import dev.usbharu.hideout.config.Config -import dev.usbharu.hideout.config.ConfigData 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.Visibility @@ -23,6 +21,7 @@ import org.junit.jupiter.api.Test import org.mockito.Mockito.anyLong import org.mockito.Mockito.eq import org.mockito.kotlin.* +import org.springframework.boot.context.config.ConfigData import utils.JsonObjectMapper.objectMapper import utils.TestApplicationConfig.testApplicationConfig import java.time.Instant diff --git a/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt index e786f016..89ac6dc2 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt @@ -3,8 +3,6 @@ package dev.usbharu.hideout.service.ap -import dev.usbharu.hideout.config.Config -import dev.usbharu.hideout.config.ConfigData import dev.usbharu.hideout.domain.model.ap.Follow import dev.usbharu.hideout.domain.model.ap.Image import dev.usbharu.hideout.domain.model.ap.Key @@ -23,6 +21,7 @@ import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.* +import org.springframework.boot.context.config.ConfigData import utils.JsonObjectMapper.objectMapper import utils.TestTransaction import java.time.Instant diff --git a/src/test/kotlin/dev/usbharu/hideout/service/user/UserServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/user/UserServiceTest.kt index 26e4ebf8..357dcbfb 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/user/UserServiceTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/user/UserServiceTest.kt @@ -2,8 +2,6 @@ package dev.usbharu.hideout.service.user -import dev.usbharu.hideout.config.Config -import dev.usbharu.hideout.config.ConfigData import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto import dev.usbharu.hideout.repository.UserRepository @@ -12,6 +10,7 @@ import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.* +import org.springframework.boot.context.config.ConfigData import utils.TestApplicationConfig.testApplicationConfig import java.security.KeyPairGenerator import kotlin.test.assertEquals From eeb2c763ae5a98cae44309aeba7ce18d9a04f744 Mon Sep 17 00:00:00 2001 From: usbharu Date: Mon, 23 Oct 2023 13:40:12 +0900 Subject: [PATCH 10/11] Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt | 1 - .../usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt index 237b2c6c..a7932b53 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt @@ -28,7 +28,6 @@ class SpringConfig { } } - @ConfigurationProperties("hideout") data class ApplicationConfig( val url: URL diff --git a/src/main/kotlin/dev/usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt index 26f5d23c..55746226 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt @@ -22,7 +22,6 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v .leftJoin(Media) .select { Posts.id eq id } .let { it.toNote() to postQueryMapper.map(it).first() } - } private suspend fun ResultRow.toNote(mediaList: List): Note { From 1e676901e7ba37bb87f282debd6a765474198ff9 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 23 Oct 2023 13:56:49 +0900 Subject: [PATCH 11/11] test: fix test --- .../service/ap/APNoteServiceImplTest.kt | 27 +++++++++---- .../ap/APReceiveFollowServiceImplTest.kt | 16 ++++++-- .../APResourceResolveServiceImplTest.kt | 15 +++++-- .../hideout/service/user/UserServiceTest.kt | 40 +++++++++++++------ 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt index bc9ab9c6..628a8eff 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt @@ -3,6 +3,8 @@ package dev.usbharu.hideout.service.ap +import dev.usbharu.hideout.config.ApplicationConfig +import dev.usbharu.hideout.config.CharacterLimit 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.Visibility @@ -21,21 +23,28 @@ import org.junit.jupiter.api.Test import org.mockito.Mockito.anyLong import org.mockito.Mockito.eq import org.mockito.kotlin.* -import org.springframework.boot.context.config.ConfigData import utils.JsonObjectMapper.objectMapper import utils.TestApplicationConfig.testApplicationConfig +import java.net.URL import java.time.Instant import kotlin.test.assertEquals class APNoteServiceImplTest { + + val userBuilder = User.UserBuilder(CharacterLimit(), ApplicationConfig(URL("https://example.com"))) + val postBuilder = Post.PostBuilder(CharacterLimit()) + @Test fun `createPost 新しい投稿`() { val mediaQueryService = mock { onBlocking { findByPostId(anyLong()) } doReturn emptyList() } + + + runTest { val followers = listOf( - User.of( + userBuilder.of( 2L, "follower", "follower.example.com", @@ -49,7 +58,7 @@ class APNoteServiceImplTest { createdAt = Instant.now(), keyId = "a" ), - User.of( + userBuilder.of( 3L, "follower2", "follower2.example.com", @@ -65,7 +74,7 @@ class APNoteServiceImplTest { ) ) val userQueryService = mock { - onBlocking { findById(eq(1L)) } doReturn User.of( + onBlocking { findById(eq(1L)) } doReturn userBuilder.of( 1L, "test", "example.com", @@ -99,9 +108,10 @@ class APNoteServiceImplTest { postService = mock(), apResourceResolveService = mock(), apRequestService = mock(), - transaction = mock() + transaction = mock(), + postBuilder = postBuilder ) - val postEntity = Post.of( + val postEntity = postBuilder.of( 1L, 1L, null, @@ -121,7 +131,7 @@ class APNoteServiceImplTest { val mediaQueryService = mock { onBlocking { findByPostId(anyLong()) } doReturn emptyList() } - Config.configData = ConfigData() + val httpClient = HttpClient( MockEngine { httpRequestData -> assertEquals("https://follower.example.com/inbox", httpRequestData.url.toString()) @@ -141,7 +151,8 @@ class APNoteServiceImplTest { postService = mock(), apResourceResolveService = mock(), apRequestService = mock(), - transaction = mock() + transaction = mock(), + postBuilder = postBuilder ) activityPubNoteService.createNoteJob( JobProps( diff --git a/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt index 89ac6dc2..38c266e1 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt @@ -3,10 +3,13 @@ package dev.usbharu.hideout.service.ap +import dev.usbharu.hideout.config.ApplicationConfig +import dev.usbharu.hideout.config.CharacterLimit import dev.usbharu.hideout.domain.model.ap.Follow import dev.usbharu.hideout.domain.model.ap.Image import dev.usbharu.hideout.domain.model.ap.Key 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.job.ReceiveFollowJob import dev.usbharu.hideout.query.UserQueryService @@ -21,12 +24,16 @@ import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.* -import org.springframework.boot.context.config.ConfigData import utils.JsonObjectMapper.objectMapper import utils.TestTransaction +import java.net.URL import java.time.Instant class APReceiveFollowServiceImplTest { + + val userBuilder = User.UserBuilder(CharacterLimit(), ApplicationConfig(URL("https://example.com"))) + val postBuilder = Post.PostBuilder(CharacterLimit()) + @Test fun `receiveFollow フォロー受付処理`() = runTest { val jobQueueParentService = mock { @@ -78,7 +85,6 @@ class APReceiveFollowServiceImplTest { @Test fun `receiveFollowJob フォロー受付処理のJob`() = runTest { - Config.configData = ConfigData() val person = Person( type = emptyList(), name = "follower", @@ -110,7 +116,7 @@ class APReceiveFollowServiceImplTest { } val userQueryService = mock { onBlocking { findByUrl(eq("https://example.com")) } doReturn - User.of( + userBuilder.of( id = 1L, name = "test", domain = "example.com", @@ -120,11 +126,13 @@ class APReceiveFollowServiceImplTest { outbox = "https://example.com/outbox", url = "https://example.com", publicKey = "", + password = "a", + privateKey = "a", createdAt = Instant.now(), keyId = "a" ) onBlocking { findByUrl(eq("https://follower.example.com")) } doReturn - User.of( + userBuilder.of( id = 2L, name = "follower", domain = "follower.example.com", diff --git a/src/test/kotlin/dev/usbharu/hideout/service/ap/resource/APResourceResolveServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/ap/resource/APResourceResolveServiceImplTest.kt index 344a07d8..87f5a553 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/ap/resource/APResourceResolveServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/ap/resource/APResourceResolveServiceImplTest.kt @@ -1,6 +1,9 @@ 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.hideout.entity.Post import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.repository.UserRepository import io.ktor.client.* @@ -16,6 +19,7 @@ import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.whenever +import java.net.URL import java.time.Instant import kotlin.test.assertEquals @@ -23,6 +27,9 @@ import kotlin.test.assertEquals @Disabled class APResourceResolveServiceImplTest { + val userBuilder = User.UserBuilder(CharacterLimit(), ApplicationConfig(URL("https://example.com"))) + val postBuilder = Post.PostBuilder(CharacterLimit()) + @Test fun `単純な一回のリクエスト`() = runTest { @@ -36,7 +43,7 @@ class APResourceResolveServiceImplTest { val userRepository = mock() whenever(userRepository.findById(any())).doReturn( - User.of( + userBuilder.of( 2L, "follower", "follower.example.com", @@ -72,7 +79,7 @@ class APResourceResolveServiceImplTest { val userRepository = mock() whenever(userRepository.findById(any())).doReturn( - User.of( + userBuilder.of( 2L, "follower", "follower.example.com", @@ -111,7 +118,7 @@ class APResourceResolveServiceImplTest { val userRepository = mock() whenever(userRepository.findById(any())).doReturn( - User.of( + userBuilder.of( 2L, "follower", "follower.example.com", @@ -161,7 +168,7 @@ class APResourceResolveServiceImplTest { val userRepository = mock() whenever(userRepository.findById(any())).doReturn( - User.of( + userBuilder.of( 2L, "follower", "follower.example.com", diff --git a/src/test/kotlin/dev/usbharu/hideout/service/user/UserServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/user/UserServiceTest.kt index 357dcbfb..663d7f40 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/user/UserServiceTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/user/UserServiceTest.kt @@ -2,24 +2,30 @@ package dev.usbharu.hideout.service.user +import dev.usbharu.hideout.config.ApplicationConfig +import dev.usbharu.hideout.config.CharacterLimit 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.entity.Post +import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.repository.UserRepository import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.* -import org.springframework.boot.context.config.ConfigData import utils.TestApplicationConfig.testApplicationConfig +import java.net.URL import java.security.KeyPairGenerator import kotlin.test.assertEquals import kotlin.test.assertNull class UserServiceTest { + val userBuilder = User.UserBuilder(CharacterLimit(), ApplicationConfig(URL("https://example.com"))) + val postBuilder = Post.PostBuilder(CharacterLimit()) @Test fun `createLocalUser ローカルユーザーを作成できる`() = runTest { - Config.configData = ConfigData(domain = "example.com", url = "https://example.com") + val userRepository = mock { onBlocking { nextId() } doReturn 110001L } @@ -29,7 +35,15 @@ class UserServiceTest { onBlocking { generateKeyPair() } doReturn generateKeyPair } val userService = - UserServiceImpl(userRepository, userAuthService, mock(), mock(), mock(), testApplicationConfig) + UserServiceImpl( + userRepository, + userAuthService, + mock(), + mock(), + mock(), + userBuilder, + testApplicationConfig, + ) userService.createLocalUser(UserCreateDto("test", "testUser", "XXXXXXXXXXXXX", "test")) verify(userRepository, times(1)).save(any()) argumentCaptor { @@ -50,20 +64,20 @@ class UserServiceTest { @Test fun `createRemoteUser リモートユーザーを作成できる`() = runTest { - Config.configData = ConfigData(domain = "remote.example.com", url = "https://remote.example.com") val userRepository = mock { 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( name = "test", - domain = "example.com", + domain = "remote.example.com", screenName = "testUser", description = "test user", - inbox = "https://example.com/inbox", - outbox = "https://example.com/outbox", - url = "https://example.com", + inbox = "https://remote.example.com/inbox", + outbox = "https://remote.example.com/outbox", + url = "https://remote.example.com", publicKey = "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----", keyId = "a", following = "", @@ -78,10 +92,10 @@ class UserServiceTest { assertEquals("test user", firstValue.description) assertNull(firstValue.password) assertEquals(113345L, firstValue.id) - assertEquals("https://example.com", firstValue.url) - assertEquals("example.com", firstValue.domain) - assertEquals("https://example.com/inbox", firstValue.inbox) - assertEquals("https://example.com/outbox", firstValue.outbox) + assertEquals("https://remote.example.com", firstValue.url) + assertEquals("remote.example.com", firstValue.domain) + assertEquals("https://remote.example.com/inbox", firstValue.inbox) + assertEquals("https://remote.example.com/outbox", firstValue.outbox) assertEquals("-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----", firstValue.publicKey) assertNull(firstValue.privateKey) }