mirror of https://github.com/usbharu/Hideout.git
feat: Postのインスタンス化時にチェックするように
This commit is contained in:
parent
7719863b80
commit
12ffbd7c51
src
main/kotlin/dev/usbharu/hideout/core/domain/model
test/kotlin
dev/usbharu/hideout
activitypub/service/objects/note
core/service
utils
|
@ -33,7 +33,6 @@ data class Actor private constructor(
|
||||||
@get:Pattern(regexp = "^[a-zA-Z0-9_-]{1,300}\$")
|
@get:Pattern(regexp = "^[a-zA-Z0-9_-]{1,300}\$")
|
||||||
@get:Size(min = 1)
|
@get:Size(min = 1)
|
||||||
val name: String,
|
val name: String,
|
||||||
@get:Pattern(regexp = "^([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\\.){1,255}[a-zA-Z]{2,}\$")
|
|
||||||
val domain: String,
|
val domain: String,
|
||||||
val screenName: String,
|
val screenName: String,
|
||||||
val description: String,
|
val description: String,
|
||||||
|
|
|
@ -18,31 +18,40 @@ package dev.usbharu.hideout.core.domain.model.post
|
||||||
|
|
||||||
import dev.usbharu.hideout.application.config.CharacterLimit
|
import dev.usbharu.hideout.application.config.CharacterLimit
|
||||||
import dev.usbharu.hideout.core.service.post.PostContentFormatter
|
import dev.usbharu.hideout.core.service.post.PostContentFormatter
|
||||||
|
import jakarta.validation.Validator
|
||||||
|
import jakarta.validation.constraints.Positive
|
||||||
|
import org.hibernate.validator.constraints.URL
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
data class Post private constructor(
|
data class Post private constructor(
|
||||||
|
@get:Positive
|
||||||
val id: Long,
|
val id: Long,
|
||||||
|
@get:Positive
|
||||||
val actorId: Long,
|
val actorId: Long,
|
||||||
val overview: String? = null,
|
val overview: String? = null,
|
||||||
val content: String,
|
val content: String,
|
||||||
val text: String,
|
val text: String,
|
||||||
|
@get:Positive
|
||||||
val createdAt: Long,
|
val createdAt: Long,
|
||||||
val visibility: Visibility,
|
val visibility: Visibility,
|
||||||
|
@get:URL
|
||||||
val url: String,
|
val url: String,
|
||||||
val repostId: Long? = null,
|
val repostId: Long? = null,
|
||||||
val replyId: Long? = null,
|
val replyId: Long? = null,
|
||||||
val sensitive: Boolean = false,
|
val sensitive: Boolean = false,
|
||||||
|
@get:URL
|
||||||
val apId: String = url,
|
val apId: String = url,
|
||||||
val mediaIds: List<Long> = emptyList(),
|
val mediaIds: List<Long> = emptyList(),
|
||||||
val delted: Boolean = false,
|
val delted: Boolean = false,
|
||||||
val emojiIds: List<Long> = emptyList()
|
val emojiIds: List<Long> = emptyList(),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class PostBuilder(
|
class PostBuilder(
|
||||||
private val characterLimit: CharacterLimit,
|
private val characterLimit: CharacterLimit,
|
||||||
private val postContentFormatter: PostContentFormatter
|
private val postContentFormatter: PostContentFormatter,
|
||||||
|
private val validator: Validator,
|
||||||
) {
|
) {
|
||||||
@Suppress("FunctionMinLength", "LongParameterList")
|
@Suppress("FunctionMinLength", "LongParameterList")
|
||||||
fun of(
|
fun of(
|
||||||
|
@ -86,7 +95,7 @@ data class Post private constructor(
|
||||||
require((repostId ?: 0) >= 0) { "repostId must be greater then or equal to 0." }
|
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." }
|
require((replyId ?: 0) >= 0) { "replyId must be greater then or equal to 0." }
|
||||||
|
|
||||||
return Post(
|
val post = Post(
|
||||||
id = id,
|
id = id,
|
||||||
actorId = actorId,
|
actorId = actorId,
|
||||||
overview = limitedOverview,
|
overview = limitedOverview,
|
||||||
|
@ -103,6 +112,14 @@ data class Post private constructor(
|
||||||
delted = false,
|
delted = false,
|
||||||
emojiIds = emojiIds
|
emojiIds = emojiIds
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val validate = validator.validate(post)
|
||||||
|
|
||||||
|
for (constraintViolation in validate) {
|
||||||
|
throw IllegalArgumentException("${constraintViolation.propertyPath} : ${constraintViolation.message}")
|
||||||
|
}
|
||||||
|
|
||||||
|
return post
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
|
@ -126,7 +143,7 @@ data class Post private constructor(
|
||||||
|
|
||||||
require(actorId >= 0) { "actorId must be greater than or equal to 0." }
|
require(actorId >= 0) { "actorId must be greater than or equal to 0." }
|
||||||
|
|
||||||
return Post(
|
val post = Post(
|
||||||
id = id,
|
id = id,
|
||||||
actorId = actorId,
|
actorId = actorId,
|
||||||
overview = null,
|
overview = null,
|
||||||
|
@ -143,6 +160,14 @@ data class Post private constructor(
|
||||||
delted = false,
|
delted = false,
|
||||||
emojiIds = emptyList()
|
emojiIds = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val validate = validator.validate(post)
|
||||||
|
|
||||||
|
for (constraintViolation in validate) {
|
||||||
|
throw IllegalArgumentException("${constraintViolation.propertyPath} : ${constraintViolation.message}")
|
||||||
|
}
|
||||||
|
|
||||||
|
return post
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
|
@ -193,7 +218,7 @@ data class Post private constructor(
|
||||||
|
|
||||||
require((replyId ?: 0) >= 0) { "replyId must be greater then or equal to 0." }
|
require((replyId ?: 0) >= 0) { "replyId must be greater then or equal to 0." }
|
||||||
|
|
||||||
return Post(
|
val post = Post(
|
||||||
id = id,
|
id = id,
|
||||||
actorId = actorId,
|
actorId = actorId,
|
||||||
overview = limitedOverview,
|
overview = limitedOverview,
|
||||||
|
@ -210,6 +235,14 @@ data class Post private constructor(
|
||||||
delted = false,
|
delted = false,
|
||||||
emojiIds = emojiIds
|
emojiIds = emojiIds
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val validate = validator.validate(post)
|
||||||
|
|
||||||
|
for (constraintViolation in validate) {
|
||||||
|
throw IllegalArgumentException("${constraintViolation.propertyPath} : ${constraintViolation.message}")
|
||||||
|
}
|
||||||
|
|
||||||
|
return post
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
|
|
|
@ -45,6 +45,7 @@ import io.ktor.http.*
|
||||||
import io.ktor.http.content.*
|
import io.ktor.http.content.*
|
||||||
import io.ktor.util.*
|
import io.ktor.util.*
|
||||||
import io.ktor.util.date.*
|
import io.ktor.util.date.*
|
||||||
|
import jakarta.validation.Validation
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
@ -60,7 +61,10 @@ import java.time.Instant
|
||||||
|
|
||||||
class APNoteServiceImplTest {
|
class APNoteServiceImplTest {
|
||||||
|
|
||||||
val postBuilder = Post.PostBuilder(CharacterLimit(), DefaultPostContentFormatter(HtmlSanitizeConfig().policy()))
|
val postBuilder = Post.PostBuilder(
|
||||||
|
CharacterLimit(), DefaultPostContentFormatter(HtmlSanitizeConfig().policy()),
|
||||||
|
Validation.buildDefaultValidatorFactory().validator
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `fetchNote(String,String) ノートが既に存在する場合はDBから取得したものを返す`() = runTest {
|
fun `fetchNote(String,String) ノートが既に存在する場合はDBから取得したものを返す`() = runTest {
|
||||||
|
@ -89,10 +93,7 @@ class APNoteServiceImplTest {
|
||||||
apUserService = mock(),
|
apUserService = mock(),
|
||||||
postService = mock(),
|
postService = mock(),
|
||||||
apResourceResolveService = mock(),
|
apResourceResolveService = mock(),
|
||||||
postBuilder = Post.PostBuilder(
|
postBuilder = postBuilder,
|
||||||
CharacterLimit(),
|
|
||||||
DefaultPostContentFormatter(HtmlSanitizeConfig().policy())
|
|
||||||
),
|
|
||||||
noteQueryService = noteQueryService,
|
noteQueryService = noteQueryService,
|
||||||
mock(),
|
mock(),
|
||||||
mock(),
|
mock(),
|
||||||
|
@ -163,10 +164,7 @@ class APNoteServiceImplTest {
|
||||||
apUserService = apUserService,
|
apUserService = apUserService,
|
||||||
postService = mock(),
|
postService = mock(),
|
||||||
apResourceResolveService = apResourceResolveService,
|
apResourceResolveService = apResourceResolveService,
|
||||||
postBuilder = Post.PostBuilder(
|
postBuilder = postBuilder,
|
||||||
CharacterLimit(),
|
|
||||||
DefaultPostContentFormatter(HtmlSanitizeConfig().policy())
|
|
||||||
),
|
|
||||||
noteQueryService = noteQueryService,
|
noteQueryService = noteQueryService,
|
||||||
mock(),
|
mock(),
|
||||||
mock { },
|
mock { },
|
||||||
|
@ -216,10 +214,7 @@ class APNoteServiceImplTest {
|
||||||
apUserService = mock(),
|
apUserService = mock(),
|
||||||
postService = mock(),
|
postService = mock(),
|
||||||
apResourceResolveService = apResourceResolveService,
|
apResourceResolveService = apResourceResolveService,
|
||||||
postBuilder = Post.PostBuilder(
|
postBuilder = postBuilder,
|
||||||
CharacterLimit(),
|
|
||||||
DefaultPostContentFormatter(HtmlSanitizeConfig().policy())
|
|
||||||
),
|
|
||||||
noteQueryService = noteQueryService,
|
noteQueryService = noteQueryService,
|
||||||
mock(),
|
mock(),
|
||||||
mock(),
|
mock(),
|
||||||
|
|
|
@ -26,6 +26,7 @@ import dev.usbharu.hideout.core.domain.model.post.Post
|
||||||
import dev.usbharu.hideout.core.domain.model.post.PostRepository
|
import dev.usbharu.hideout.core.domain.model.post.PostRepository
|
||||||
import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository
|
import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository
|
||||||
import dev.usbharu.hideout.core.service.timeline.TimelineService
|
import dev.usbharu.hideout.core.service.timeline.TimelineService
|
||||||
|
import jakarta.validation.Validation
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
@ -56,7 +57,7 @@ class PostServiceImplTest {
|
||||||
private var postBuilder: Post.PostBuilder = Post.PostBuilder(
|
private var postBuilder: Post.PostBuilder = Post.PostBuilder(
|
||||||
CharacterLimit(), DefaultPostContentFormatter(
|
CharacterLimit(), DefaultPostContentFormatter(
|
||||||
HtmlSanitizeConfig().policy()
|
HtmlSanitizeConfig().policy()
|
||||||
)
|
), Validation.buildDefaultValidatorFactory().validator
|
||||||
)
|
)
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
|
|
|
@ -20,11 +20,8 @@ package dev.usbharu.hideout.core.service.user
|
||||||
|
|
||||||
import dev.usbharu.hideout.application.config.ApplicationConfig
|
import dev.usbharu.hideout.application.config.ApplicationConfig
|
||||||
import dev.usbharu.hideout.application.config.CharacterLimit
|
import dev.usbharu.hideout.application.config.CharacterLimit
|
||||||
import dev.usbharu.hideout.application.config.HtmlSanitizeConfig
|
|
||||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||||
import dev.usbharu.hideout.core.domain.model.post.Post
|
|
||||||
import dev.usbharu.hideout.core.service.post.DefaultPostContentFormatter
|
|
||||||
import jakarta.validation.Validation
|
import jakarta.validation.Validation
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
|
@ -43,7 +40,6 @@ class ActorServiceTest {
|
||||||
ApplicationConfig(URL("https://example.com")),
|
ApplicationConfig(URL("https://example.com")),
|
||||||
Validation.buildDefaultValidatorFactory().validator
|
Validation.buildDefaultValidatorFactory().validator
|
||||||
)
|
)
|
||||||
val postBuilder = Post.PostBuilder(CharacterLimit(), DefaultPostContentFormatter(HtmlSanitizeConfig().policy()))
|
|
||||||
@Test
|
@Test
|
||||||
fun `createLocalUser ローカルユーザーを作成できる`() = runTest {
|
fun `createLocalUser ローカルユーザーを作成できる`() = runTest {
|
||||||
|
|
||||||
|
|
|
@ -22,13 +22,18 @@ import dev.usbharu.hideout.application.service.id.TwitterSnowflakeIdGenerateServ
|
||||||
import dev.usbharu.hideout.core.domain.model.post.Post
|
import dev.usbharu.hideout.core.domain.model.post.Post
|
||||||
import dev.usbharu.hideout.core.domain.model.post.Visibility
|
import dev.usbharu.hideout.core.domain.model.post.Visibility
|
||||||
import dev.usbharu.hideout.core.service.post.DefaultPostContentFormatter
|
import dev.usbharu.hideout.core.service.post.DefaultPostContentFormatter
|
||||||
|
import jakarta.validation.Validation
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
object PostBuilder {
|
object PostBuilder {
|
||||||
|
|
||||||
private val postBuilder =
|
private val postBuilder =
|
||||||
Post.PostBuilder(CharacterLimit(), DefaultPostContentFormatter(HtmlSanitizeConfig().policy()))
|
Post.PostBuilder(
|
||||||
|
CharacterLimit(),
|
||||||
|
DefaultPostContentFormatter(HtmlSanitizeConfig().policy()),
|
||||||
|
Validation.buildDefaultValidatorFactory().validator
|
||||||
|
)
|
||||||
|
|
||||||
private val idGenerator = TwitterSnowflakeIdGenerateService
|
private val idGenerator = TwitterSnowflakeIdGenerateService
|
||||||
|
|
||||||
|
@ -39,7 +44,7 @@ object PostBuilder {
|
||||||
text: String = "Hello World",
|
text: String = "Hello World",
|
||||||
createdAt: Long = Instant.now().toEpochMilli(),
|
createdAt: Long = Instant.now().toEpochMilli(),
|
||||||
visibility: Visibility = Visibility.PUBLIC,
|
visibility: Visibility = Visibility.PUBLIC,
|
||||||
url: String = "https://example.com/users/$userId/posts/$id"
|
url: String = "https://example.com/users/$userId/posts/$id",
|
||||||
): Post {
|
): Post {
|
||||||
return postBuilder.of(
|
return postBuilder.of(
|
||||||
id = id,
|
id = id,
|
||||||
|
|
Loading…
Reference in New Issue