diff --git a/src/main/kotlin/dev/usbharu/hideout/Application.kt b/src/main/kotlin/dev/usbharu/hideout/Application.kt index c8bfc06e..254d7a59 100644 --- a/src/main/kotlin/dev/usbharu/hideout/Application.kt +++ b/src/main/kotlin/dev/usbharu/hideout/Application.kt @@ -14,6 +14,7 @@ import dev.usbharu.hideout.repository.IUserRepository import dev.usbharu.hideout.routing.register import dev.usbharu.hideout.service.activitypub.ActivityPubService import dev.usbharu.hideout.service.activitypub.ActivityPubUserService +import dev.usbharu.hideout.service.api.IPostApiService import dev.usbharu.hideout.service.api.IUserApiService import dev.usbharu.hideout.service.auth.HttpSignatureVerifyService import dev.usbharu.hideout.service.auth.IJwtService @@ -23,7 +24,6 @@ import dev.usbharu.hideout.service.core.IdGenerateService import dev.usbharu.hideout.service.core.TwitterSnowflakeIdGenerateService import dev.usbharu.hideout.service.job.JobQueueParentService import dev.usbharu.hideout.service.job.KJobJobQueueParentService -import dev.usbharu.hideout.service.post.IPostService import dev.usbharu.hideout.service.user.IUserAuthService import dev.usbharu.hideout.service.user.IUserService import dev.usbharu.kjob.exposed.ExposedKJob @@ -107,12 +107,12 @@ fun Application.parent() { inject().value, ) configureRouting( - httpSignatureVerifyService = inject().value, - activityPubService = inject().value, - userService = inject().value, - activityPubUserService = inject().value, - postService = inject().value, - userApiService = inject().value, + httpSignatureVerifyService = inject().value, + activityPubService = inject().value, + userService = inject().value, + activityPubUserService = inject().value, + postService = inject().value, + userApiService = inject().value, ) } diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt index a424a5fa..6a52f394 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt @@ -5,13 +5,12 @@ import dev.usbharu.hideout.routing.activitypub.outbox import dev.usbharu.hideout.routing.activitypub.usersAP import dev.usbharu.hideout.routing.api.internal.v1.posts import dev.usbharu.hideout.routing.api.internal.v1.users -import dev.usbharu.hideout.routing.api.mastodon.v1.statuses import dev.usbharu.hideout.routing.wellknown.webfinger import dev.usbharu.hideout.service.activitypub.ActivityPubService import dev.usbharu.hideout.service.activitypub.ActivityPubUserService +import dev.usbharu.hideout.service.api.IPostApiService import dev.usbharu.hideout.service.api.IUserApiService import dev.usbharu.hideout.service.auth.HttpSignatureVerifyService -import dev.usbharu.hideout.service.post.IPostService import dev.usbharu.hideout.service.user.IUserService import io.ktor.server.application.* import io.ktor.server.plugins.autohead.* @@ -19,12 +18,12 @@ import io.ktor.server.routing.* @Suppress("LongParameterList") fun Application.configureRouting( - httpSignatureVerifyService: HttpSignatureVerifyService, - activityPubService: ActivityPubService, - userService: IUserService, - activityPubUserService: ActivityPubUserService, - postService: IPostService, - userApiService: IUserApiService + httpSignatureVerifyService: HttpSignatureVerifyService, + activityPubService: ActivityPubService, + userService: IUserService, + activityPubUserService: ActivityPubUserService, + postService: IPostApiService, + userApiService: IUserApiService ) { install(AutoHeadResponse) routing { @@ -32,10 +31,6 @@ fun Application.configureRouting( outbox() usersAP(activityPubUserService, userService) webfinger(userService) - - route("/api/v1") { - statuses(postService) - } route("/api/internal/v1") { posts(postService) users(userService, userApiService) diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Posts.kt b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Posts.kt index 34772aff..ee533159 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Posts.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Posts.kt @@ -1,13 +1,11 @@ package dev.usbharu.hideout.routing.api.internal.v1 -import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.domain.model.hideout.dto.PostCreateDto import dev.usbharu.hideout.domain.model.hideout.form.Post import dev.usbharu.hideout.exception.ParameterNotExistException import dev.usbharu.hideout.exception.PostNotFoundException import dev.usbharu.hideout.plugins.TOKEN_AUTH -import dev.usbharu.hideout.service.post.IPostService -import dev.usbharu.hideout.util.AcctUtil +import dev.usbharu.hideout.service.api.IPostApiService import dev.usbharu.hideout.util.InstantParseUtil import io.ktor.http.* import io.ktor.server.application.* @@ -18,7 +16,7 @@ import io.ktor.server.response.* import io.ktor.server.routing.* @Suppress("LongMethod") -fun Route.posts(postService: IPostService) { +fun Route.posts(postApiService: IPostApiService) { route("/posts") { authenticate(TOKEN_AUTH) { post { @@ -27,14 +25,14 @@ fun Route.posts(postService: IPostService) { val receive = call.receive() val postCreateDto = PostCreateDto( - text = receive.text, - overview = receive.overview, - visibility = receive.visibility, - repostId = receive.repostId, - repolyId = receive.replyId, - userId = userId + text = receive.text, + overview = receive.overview, + visibility = receive.visibility, + repostId = receive.repostId, + repolyId = receive.replyId, + userId = userId ) - val create = postService.create(postCreateDto) + val create = postApiService.createPost(postCreateDto) call.response.header("Location", create.url) call.respond(HttpStatusCode.OK) } @@ -47,16 +45,13 @@ fun Route.posts(postService: IPostService) { val minId = call.request.queryParameters["minId"]?.toLong() val maxId = call.request.queryParameters["maxId"]?.toLong() val limit = call.request.queryParameters["limit"]?.toInt() - call.respond(HttpStatusCode.OK, postService.findAll(since, until, minId, maxId, limit, userId)) + call.respond(HttpStatusCode.OK, postApiService.getAll(since, until, minId, maxId, limit, userId)) } get("/{id}") { val userId = call.principal()?.payload?.getClaim("uid")?.asLong() val id = call.parameters["id"]?.toLong() ?: throw ParameterNotExistException("Parameter(id='postsId') does not exist.") - val post = ( - postService.findByIdForUser(id, userId) - ?: throw PostNotFoundException("$id was not found or is not authorized.") - ) + val post = postApiService.getById(id, userId) call.respond(post) } } @@ -66,28 +61,15 @@ fun Route.posts(postService: IPostService) { get { val userId = call.principal()?.payload?.getClaim("uid")?.asLong() val targetUserName = call.parameters["name"] - ?: throw ParameterNotExistException("Parameter(name='userName@domain') does not exist.") - val targetUserId = targetUserName.toLongOrNull() - val posts = if (targetUserId == null) { - val acct = AcctUtil.parse(targetUserName) - postService.findByUserNameAndDomainForUser( - acct.username, - acct.domain ?: Config.configData.domain, - forUserId = userId - ) - } else { - postService.findByUserIdForUser(targetUserId, forUserId = userId) - } + ?: throw ParameterNotExistException("Parameter(name='userName@domain') does not exist.") + val posts = postApiService.getByUser(targetUserName, userId = userId) call.respond(posts) } get("/{id}") { val userId = call.principal()?.payload?.getClaim("uid")?.asLong() val id = call.parameters["id"]?.toLong() - ?: throw ParameterNotExistException("Parameter(name='postsId' does not exist.") - val post = ( - postService.findByIdForUser(id, userId) - ?: throw PostNotFoundException("$id was not found or is not authorized.") - ) + ?: throw ParameterNotExistException("Parameter(name='postsId' does not exist.") + val post = postApiService.getById(id, userId) call.respond(post) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt index b9a8b068..9f357120 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt @@ -43,7 +43,7 @@ fun Route.users(userService: IUserService, userApiService: IUserApiService) { get { val userParameter = ( call.parameters["name"] - ?: throw ParameterNotExistException("Parameter(name='userName@domain') does not exist.") + ?: throw ParameterNotExistException("Parameter(name='userName@domain') does not exist.") ) if (userParameter.toLongOrNull() != null) { return@get call.respond(userApiService.findById(userParameter.toLong())) @@ -91,7 +91,7 @@ fun Route.users(userService: IUserService, userApiService: IUserApiService) { get { val userParameter = ( call.parameters["name"] - ?: throw ParameterNotExistException("Parameter(name='userName@domain') does not exist.") + ?: throw ParameterNotExistException("Parameter(name='userName@domain') does not exist.") ) if (userParameter.toLongOrNull() != null) { return@get call.respond(userApiService.findFollowings(userParameter.toLong())) diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/api/mastodon/v1/Statuses.kt b/src/main/kotlin/dev/usbharu/hideout/routing/api/mastodon/v1/Statuses.kt index 5d83463e..ba757257 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/api/mastodon/v1/Statuses.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/api/mastodon/v1/Statuses.kt @@ -1,21 +1,18 @@ package dev.usbharu.hideout.routing.api.mastodon.v1 -import dev.usbharu.hideout.service.post.IPostService -import io.ktor.server.routing.* - -@Suppress("UnusedPrivateMember") -fun Route.statuses(postService: IPostService) { -// route("/statuses") { -// post { -// val status: StatusForPost = call.receive() -// val post = dev.usbharu.hideout.domain.model.hideout.form.Post( -// userId = status.userId, -// createdAt = System.currentTimeMillis(), -// text = status.status, -// visibility = 1 -// ) -// postService.create(post) -// call.respond(status) -// } -// } -} +// @Suppress("UnusedPrivateMember") +// fun Route.statuses(postService: IPostService) { +// // route("/statuses") { +// // post { +// // val status: StatusForPost = call.receive() +// // val post = dev.usbharu.hideout.domain.model.hideout.form.Post( +// // userId = status.userId, +// // createdAt = System.currentTimeMillis(), +// // text = status.status, +// // visibility = 1 +// // ) +// // postService.create(post) +// // call.respond(status) +// // } +// // } +// } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/api/IPostApiService.kt b/src/main/kotlin/dev/usbharu/hideout/service/api/IPostApiService.kt new file mode 100644 index 00000000..d54d48cb --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/api/IPostApiService.kt @@ -0,0 +1,24 @@ +package dev.usbharu.hideout.service.api + +import dev.usbharu.hideout.domain.model.hideout.dto.PostCreateDto +import dev.usbharu.hideout.domain.model.hideout.entity.Post +import java.time.Instant + +interface IPostApiService { + suspend fun createPost(postCreateDto: PostCreateDto): Post + suspend fun getById(id: Long, userId: Long?): Post + suspend fun getAll(since: Instant? = null, + until: Instant? = null, + minId: Long? = null, + maxId: Long? = null, + limit: Int? = null, + userId: Long? = null): List + + suspend fun getByUser(nameOrId: String, + since: Instant? = null, + until: Instant? = null, + minId: Long? = null, + maxId: Long? = null, + limit: Int? = null, + userId: Long? = null): List +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/post/IPostService.kt b/src/main/kotlin/dev/usbharu/hideout/service/post/IPostService.kt index af290950..970eaa26 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/post/IPostService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/post/IPostService.kt @@ -1,61 +1,9 @@ package dev.usbharu.hideout.service.post -import dev.usbharu.hideout.config.Config -import dev.usbharu.hideout.domain.model.hideout.dto.PostCreateDto +import dev.usbharu.hideout.domain.model.ap.Note import dev.usbharu.hideout.domain.model.hideout.entity.Post -import java.time.Instant -@Suppress("LongParameterList") interface IPostService { - suspend fun create(post: Post): Post - suspend fun create(post: PostCreateDto): Post - suspend fun findAll( - since: Instant? = null, - until: Instant? = null, - minId: Long? = null, - maxId: Long? = null, - limit: Int? = 10, - userId: Long? = null - ): List - - suspend fun findById(id: String): Post - - /** - * 権限を考慮して投稿を取得します。 - * - * @param id - * @param userId - * @return - */ - suspend fun findByIdForUser(id: Long, userId: Long?): Post? - - /** - * 権限を考慮してユーザーの投稿を取得します。 - * - * @param userId - * @param forUserId - * @return - */ - suspend fun findByUserIdForUser( - userId: Long, - since: Instant? = null, - until: Instant? = null, - minId: Long? = null, - maxId: Long? = null, - limit: Int? = null, - forUserId: Long? = null - ): List - - suspend fun findByUserNameAndDomainForUser( - userName: String, - domain: String = Config.configData.domain, - since: Instant? = null, - until: Instant? = null, - minId: Long? = null, - maxId: Long? = null, - limit: Int? = null, - forUserId: Long? = null - ): List - - suspend fun delete(id: String) + suspend fun createLocal(post: Post): Post + suspend fun createRemote(note: Note): Post } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/post/PostService.kt b/src/main/kotlin/dev/usbharu/hideout/service/post/PostService.kt deleted file mode 100644 index 3ec2b071..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/service/post/PostService.kt +++ /dev/null @@ -1,130 +0,0 @@ -package dev.usbharu.hideout.service.post - -import dev.usbharu.hideout.domain.model.hideout.dto.PostCreateDto -import dev.usbharu.hideout.domain.model.hideout.entity.Post -import dev.usbharu.hideout.domain.model.hideout.entity.Visibility -import dev.usbharu.hideout.repository.IPostRepository -import dev.usbharu.hideout.repository.Posts -import dev.usbharu.hideout.repository.UsersFollowers -import dev.usbharu.hideout.repository.toPost -import dev.usbharu.hideout.service.activitypub.ActivityPubNoteService -import dev.usbharu.hideout.service.user.IUserService -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.SqlExpressionBuilder.inSubQuery -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.orIfNotNull -import org.jetbrains.exposed.sql.orWhere -import org.jetbrains.exposed.sql.select -import org.jetbrains.exposed.sql.transactions.transaction -import org.koin.core.annotation.Single -import org.slf4j.LoggerFactory -import java.time.Instant - -@Single -class PostService( - private val postRepository: IPostRepository, - private val activityPubNoteService: ActivityPubNoteService, - private val userService: IUserService -) : IPostService { - - private val logger = LoggerFactory.getLogger(this::class.java) - - override suspend fun create(post: Post): Post { - logger.debug("create post={}", post) - val postEntity = postRepository.save(post) - activityPubNoteService.createNote(postEntity) - return post - } - - override suspend fun create(post: PostCreateDto): Post { - logger.debug("create post={}", post) - val user = userService.findById(post.userId) - val id = postRepository.generateId() - val postEntity = Post( - id = id, - userId = user.id, - overview = null, - text = post.text, - createdAt = Instant.now().toEpochMilli(), - visibility = Visibility.PUBLIC, - url = "${user.url}/posts/$id", - repostId = null, - replyId = null - ) - postRepository.save(postEntity) - return postEntity - } - - override suspend fun findAll( - since: Instant?, - until: Instant?, - minId: Long?, - maxId: Long?, - limit: Int?, - userId: Long? - ): List { - return transaction { - val select = Posts.select { - Posts.visibility.eq(Visibility.PUBLIC.ordinal) - } - if (userId != null) { - select.orWhere { - Posts.userId.inSubQuery( - UsersFollowers.slice(UsersFollowers.userId).select(UsersFollowers.followerId eq userId) - ) - } - } - select.map { it.toPost() } - } - } - - override suspend fun findById(id: String): Post { - TODO("Not yet implemented") - } - - override suspend fun findByIdForUser(id: Long, userId: Long?): Post? { - return transaction { - val select = Posts.select( - Posts.id.eq(id).and( - Posts.visibility.eq(Visibility.PUBLIC.ordinal).orIfNotNull( - userId?.let { - Posts.userId.inSubQuery( - UsersFollowers.slice(UsersFollowers.userId).select(UsersFollowers.followerId.eq(userId)) - ) - } - ) - ) - ) - select.singleOrNull()?.toPost() - } - } - - override suspend fun findByUserIdForUser( - userId: Long, - since: Instant?, - until: Instant?, - minId: Long?, - maxId: Long?, - limit: Int?, - forUserId: Long? - ): List { - TODO("Not yet implemented") - } - - override suspend fun findByUserNameAndDomainForUser( - userName: String, - domain: String, - since: Instant?, - until: Instant?, - minId: Long?, - maxId: Long?, - limit: Int?, - forUserId: Long? - ): List { - TODO("Not yet implemented") - } - - override suspend fun delete(id: String) { - TODO("Not yet implemented") - } -} diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/PostsTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/PostsTest.kt index af38a764..50b54ded 100644 --- a/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/PostsTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/PostsTest.kt @@ -10,7 +10,7 @@ import dev.usbharu.hideout.domain.model.hideout.entity.Visibility import dev.usbharu.hideout.plugins.TOKEN_AUTH import dev.usbharu.hideout.plugins.configureSecurity import dev.usbharu.hideout.plugins.configureSerialization -import dev.usbharu.hideout.service.post.IPostService +import dev.usbharu.hideout.service.api.IPostApiService import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* @@ -42,24 +42,24 @@ class PostsTest { createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1" ), - Post( - id = 123456, - userId = 4322, - text = "test2", - visibility = Visibility.PUBLIC, - createdAt = Instant.now().toEpochMilli(), - url = "https://example.com/posts/2" - ) + Post( + id = 123456, + userId = 4322, + text = "test2", + visibility = Visibility.PUBLIC, + createdAt = Instant.now().toEpochMilli(), + url = "https://example.com/posts/2" + ) ) - val postService = mock { + val postService = mock { onBlocking { - findAll( - since = anyOrNull(), - until = anyOrNull(), - minId = anyOrNull(), - maxId = anyOrNull(), - limit = anyOrNull(), - userId = isNull() + getAll( + since = anyOrNull(), + until = anyOrNull(), + minId = anyOrNull(), + maxId = anyOrNull(), + limit = anyOrNull(), + userId = isNull() ) } doReturn posts } @@ -118,15 +118,15 @@ class PostsTest { ) ) - val postService = mock { + val postService = mock { onBlocking { - findAll( - since = anyOrNull(), - until = anyOrNull(), - minId = anyOrNull(), - maxId = anyOrNull(), - limit = anyOrNull(), - userId = isNotNull() + getAll( + since = anyOrNull(), + until = anyOrNull(), + minId = anyOrNull(), + maxId = anyOrNull(), + limit = anyOrNull(), + userId = isNotNull() ) } doReturn posts } @@ -158,15 +158,15 @@ class PostsTest { config = ApplicationConfig("empty.conf") } val post = Post( - 12345, - 1234, - text = "aaa", - visibility = Visibility.PUBLIC, - createdAt = Instant.now().toEpochMilli(), - url = "https://example.com/posts/1" + 12345, + 1234, + text = "aaa", + visibility = Visibility.PUBLIC, + createdAt = Instant.now().toEpochMilli(), + url = "https://example.com/posts/1" ) - val postService = mock { - onBlocking { findByIdForUser(any(), anyOrNull()) } doReturn post + val postService = mock { + onBlocking { getById(any(), anyOrNull()) } doReturn post } application { configureSerialization() @@ -189,15 +189,15 @@ class PostsTest { config = ApplicationConfig("empty.conf") } val post = Post( - 12345, - 1234, - text = "aaa", - visibility = Visibility.FOLLOWERS, - createdAt = Instant.now().toEpochMilli(), - url = "https://example.com/posts/1" + 12345, + 1234, + text = "aaa", + visibility = Visibility.FOLLOWERS, + createdAt = Instant.now().toEpochMilli(), + url = "https://example.com/posts/1" ) - val postService = mock { - onBlocking { findByIdForUser(any(), isNotNull()) } doReturn post + val postService = mock { + onBlocking { getById(any(), isNotNull()) } doReturn post } val claim = mock { on { asLong() } doReturn 1234 @@ -239,17 +239,17 @@ class PostsTest { val payload = mock { on { getClaim(eq("uid")) } doReturn claim } - val postService = mock { - onBlocking { create(any()) } doAnswer { + val postService = mock { + onBlocking { createPost(any()) } doAnswer { val argument = it.getArgument(0) Post( - 123L, - argument.userId, - null, - argument.text, - Instant.now().toEpochMilli(), - Visibility.PUBLIC, - "https://example.com" + 123L, + argument.userId, + null, + argument.text, + Instant.now().toEpochMilli(), + Visibility.PUBLIC, + "https://example.com" ) } } @@ -280,7 +280,7 @@ class PostsTest { assertEquals("https://example.com", headers["Location"]) } argumentCaptor { - verify(postService).create(capture()) + verify(postService).createPost(capture()) assertEquals(PostCreateDto("test", userId = 1234), firstValue) } } @@ -299,25 +299,25 @@ class PostsTest { createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1" ), - Post( - id = 123456, - userId = 1, - text = "test2", - visibility = Visibility.PUBLIC, - createdAt = Instant.now().toEpochMilli(), - url = "https://example.com/posts/2" - ) + Post( + id = 123456, + userId = 1, + text = "test2", + visibility = Visibility.PUBLIC, + createdAt = Instant.now().toEpochMilli(), + url = "https://example.com/posts/2" + ) ) - val postService = mock { + val postService = mock { onBlocking { - findByUserIdForUser( - userId = any(), - since = anyOrNull(), - until = anyOrNull(), - minId = anyOrNull(), - maxId = anyOrNull(), - limit = anyOrNull(), - forUserId = anyOrNull() + getByUser( + nameOrId = any(), + since = anyOrNull(), + until = anyOrNull(), + minId = anyOrNull(), + maxId = anyOrNull(), + limit = anyOrNull(), + userId = anyOrNull() ) } doReturn posts } @@ -351,26 +351,25 @@ class PostsTest { createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1" ), - Post( - id = 123456, - userId = 1, - text = "test2", - visibility = Visibility.PUBLIC, - createdAt = Instant.now().toEpochMilli(), - url = "https://example.com/posts/2" - ) + Post( + id = 123456, + userId = 1, + text = "test2", + visibility = Visibility.PUBLIC, + createdAt = Instant.now().toEpochMilli(), + url = "https://example.com/posts/2" + ) ) - val postService = mock { + val postService = mock { onBlocking { - findByUserNameAndDomainForUser( - userName = eq("test1"), - domain = eq(Config.configData.domain), - since = anyOrNull(), - until = anyOrNull(), - minId = anyOrNull(), - maxId = anyOrNull(), - limit = anyOrNull(), - forUserId = anyOrNull() + getByUser( + nameOrId = eq("test1"), + since = anyOrNull(), + until = anyOrNull(), + minId = anyOrNull(), + maxId = anyOrNull(), + limit = anyOrNull(), + userId = anyOrNull() ) } doReturn posts } @@ -404,26 +403,25 @@ class PostsTest { createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1" ), - Post( - id = 123456, - userId = 1, - text = "test2", - visibility = Visibility.PUBLIC, - createdAt = Instant.now().toEpochMilli(), - url = "https://example.com/posts/2" - ) + Post( + id = 123456, + userId = 1, + text = "test2", + visibility = Visibility.PUBLIC, + createdAt = Instant.now().toEpochMilli(), + url = "https://example.com/posts/2" + ) ) - val postService = mock { + val postService = mock { onBlocking { - findByUserNameAndDomainForUser( - userName = eq("test1"), - domain = eq("example.com"), - since = anyOrNull(), - until = anyOrNull(), - minId = anyOrNull(), - maxId = anyOrNull(), - limit = anyOrNull(), - forUserId = anyOrNull() + getByUser( + nameOrId = eq("test1@example.com"), + since = anyOrNull(), + until = anyOrNull(), + minId = anyOrNull(), + maxId = anyOrNull(), + limit = anyOrNull(), + userId = anyOrNull() ) } doReturn posts } @@ -457,26 +455,25 @@ class PostsTest { createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1" ), - Post( - id = 123456, - userId = 1, - text = "test2", - visibility = Visibility.PUBLIC, - createdAt = Instant.now().toEpochMilli(), - url = "https://example.com/posts/2" - ) + Post( + id = 123456, + userId = 1, + text = "test2", + visibility = Visibility.PUBLIC, + createdAt = Instant.now().toEpochMilli(), + url = "https://example.com/posts/2" + ) ) - val postService = mock { + val postService = mock { onBlocking { - findByUserNameAndDomainForUser( - userName = eq("test1"), - domain = eq("example.com"), - since = anyOrNull(), - until = anyOrNull(), - minId = anyOrNull(), - maxId = anyOrNull(), - limit = anyOrNull(), - forUserId = anyOrNull() + getByUser( + nameOrId = eq("@test1@example.com"), + since = anyOrNull(), + until = anyOrNull(), + minId = anyOrNull(), + maxId = anyOrNull(), + limit = anyOrNull(), + userId = anyOrNull() ) } doReturn posts } @@ -502,15 +499,15 @@ class PostsTest { config = ApplicationConfig("empty.conf") } val post = Post( - id = 123456, - userId = 1, - text = "test2", - visibility = Visibility.PUBLIC, - createdAt = Instant.now().toEpochMilli(), - url = "https://example.com/posts/2" + id = 123456, + userId = 1, + text = "test2", + visibility = Visibility.PUBLIC, + createdAt = Instant.now().toEpochMilli(), + url = "https://example.com/posts/2" ) - val postService = mock { - onBlocking { findByIdForUser(eq(12345L), anyOrNull()) } doReturn post + val postService = mock { + onBlocking { getById(eq(12345L), anyOrNull()) } doReturn post } application { configureSerialization() @@ -534,15 +531,15 @@ class PostsTest { config = ApplicationConfig("empty.conf") } val post = Post( - id = 123456, - userId = 1, - text = "test2", - visibility = Visibility.PUBLIC, - createdAt = Instant.now().toEpochMilli(), - url = "https://example.com/posts/2" + id = 123456, + userId = 1, + text = "test2", + visibility = Visibility.PUBLIC, + createdAt = Instant.now().toEpochMilli(), + url = "https://example.com/posts/2" ) - val postService = mock { - onBlocking { findByIdForUser(eq(12345L), anyOrNull()) } doReturn post + val postService = mock { + onBlocking { getById(eq(12345L), anyOrNull()) } doReturn post } application { configureSerialization() @@ -566,15 +563,15 @@ class PostsTest { config = ApplicationConfig("empty.conf") } val post = Post( - id = 123456, - userId = 1, - text = "test2", - visibility = Visibility.PUBLIC, - createdAt = Instant.now().toEpochMilli(), - url = "https://example.com/posts/2" + id = 123456, + userId = 1, + text = "test2", + visibility = Visibility.PUBLIC, + createdAt = Instant.now().toEpochMilli(), + url = "https://example.com/posts/2" ) - val postService = mock { - onBlocking { findByIdForUser(eq(12345L), anyOrNull()) } doReturn post + val postService = mock { + onBlocking { getById(eq(12345L), anyOrNull()) } doReturn post } application { configureSerialization() @@ -598,15 +595,15 @@ class PostsTest { config = ApplicationConfig("empty.conf") } val post = Post( - id = 123456, - userId = 1, - text = "test2", - visibility = Visibility.PUBLIC, - createdAt = Instant.now().toEpochMilli(), - url = "https://example.com/posts/2" + id = 123456, + userId = 1, + text = "test2", + visibility = Visibility.PUBLIC, + createdAt = Instant.now().toEpochMilli(), + url = "https://example.com/posts/2" ) - val postService = mock { - onBlocking { findByIdForUser(eq(12345L), anyOrNull()) } doReturn post + val postService = mock { + onBlocking { getById(eq(12345L), anyOrNull()) } doReturn post } application { configureSerialization() diff --git a/src/test/kotlin/dev/usbharu/hideout/service/post/PostServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/post/PostServiceTest.kt deleted file mode 100644 index 92c517a6..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/service/post/PostServiceTest.kt +++ /dev/null @@ -1,166 +0,0 @@ -@file:OptIn(ExperimentalCoroutinesApi::class) - -package dev.usbharu.hideout.service.post - -import dev.usbharu.hideout.domain.model.hideout.entity.Post -import dev.usbharu.hideout.domain.model.hideout.entity.Visibility -import dev.usbharu.hideout.repository.Posts -import dev.usbharu.hideout.repository.UsersFollowers -import dev.usbharu.hideout.service.core.TwitterSnowflakeIdGenerateService -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runTest -import org.jetbrains.exposed.sql.Database -import org.jetbrains.exposed.sql.SchemaUtils -import org.jetbrains.exposed.sql.batchInsert -import org.jetbrains.exposed.sql.insert -import org.jetbrains.exposed.sql.transactions.transaction -import org.junit.jupiter.api.AfterEach -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.mockito.kotlin.mock -import java.time.Instant -import kotlin.test.assertContentEquals - -class PostServiceTest { - - lateinit var db: Database - - @BeforeEach - fun setUp() { - db = Database.connect("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", driver = "org.h2.Driver") - transaction(db) { - SchemaUtils.create(Posts) - connection.prepareStatement("SET REFERENTIAL_INTEGRITY FALSE", false).executeUpdate() - } - } - - @AfterEach - fun tearDown() { - transaction(db) { - SchemaUtils.drop(Posts) - } - } - - @Test - fun `findAll 公開投稿を取得できる`() = runTest { - val postService = PostService(mock(), mock(), mock()) - - suspend fun createPost(userId: Long, text: String, visibility: Visibility = Visibility.PUBLIC): Post { - return Post( - TwitterSnowflakeIdGenerateService.generateId(), - userId, - null, - text, - Instant.now().toEpochMilli(), - visibility, - "https://example.com${(userId.toString() + text).hashCode()}" - ) - } - - val userA: Long = 1 - val userB: Long = 2 - - val posts = listOf( - createPost(userA, "hello"), - createPost(userA, "hello1"), - createPost(userA, "hello2"), - createPost(userA, "hello3"), - createPost(userA, "hello4"), - createPost(userA, "hello5"), - createPost(userA, "hello6"), - createPost(userB, "good bay ", Visibility.FOLLOWERS), - createPost(userB, "good bay1", Visibility.FOLLOWERS), - createPost(userB, "good bay2", Visibility.FOLLOWERS), - createPost(userB, "good bay3", Visibility.FOLLOWERS), - createPost(userB, "good bay4", Visibility.FOLLOWERS), - createPost(userB, "good bay5", Visibility.FOLLOWERS), - createPost(userB, "good bay6", Visibility.FOLLOWERS), - ) - - transaction { - Posts.batchInsert(posts) { - this[Posts.id] = it.id - this[Posts.userId] = it.userId - this[Posts.overview] = it.overview - this[Posts.text] = it.text - this[Posts.createdAt] = it.createdAt - this[Posts.visibility] = it.visibility.ordinal - this[Posts.url] = it.url - this[Posts.replyId] = it.replyId - this[Posts.repostId] = it.repostId - this[Posts.sensitive] = it.sensitive - this[Posts.apId] = it.apId - } - } - - val expect = posts.filter { it.visibility == Visibility.PUBLIC } - - val actual = postService.findAll() - assertContentEquals(expect, actual) - } - - @Test - fun `findAll フォロー限定投稿を見れる`() = runTest { - val postService = PostService(mock(), mock(), mock()) - - suspend fun createPost(userId: Long, text: String, visibility: Visibility = Visibility.PUBLIC): Post { - return Post( - TwitterSnowflakeIdGenerateService.generateId(), - userId, - null, - text, - Instant.now().toEpochMilli(), - visibility, - "https://example.com${(userId.toString() + text).hashCode()}" - ) - } - - val userA: Long = 1 - val userB: Long = 2 - - val posts = listOf( - createPost(userA, "hello"), - createPost(userA, "hello1"), - createPost(userA, "hello2"), - createPost(userA, "hello3"), - createPost(userA, "hello4"), - createPost(userA, "hello5"), - createPost(userA, "hello6"), - createPost(userB, "good bay ", Visibility.FOLLOWERS), - createPost(userB, "good bay1", Visibility.FOLLOWERS), - createPost(userB, "good bay2", Visibility.FOLLOWERS), - createPost(userB, "good bay3", Visibility.FOLLOWERS), - createPost(userB, "good bay4", Visibility.FOLLOWERS), - createPost(userB, "good bay5", Visibility.FOLLOWERS), - createPost(userB, "good bay6", Visibility.FOLLOWERS), - ) - - transaction(db) { - SchemaUtils.create(UsersFollowers) - } - - transaction { - Posts.batchInsert(posts) { - this[Posts.id] = it.id - this[Posts.userId] = it.userId - this[Posts.overview] = it.overview - this[Posts.text] = it.text - this[Posts.createdAt] = it.createdAt - this[Posts.visibility] = it.visibility.ordinal - this[Posts.url] = it.url - this[Posts.replyId] = it.replyId - this[Posts.repostId] = it.repostId - this[Posts.sensitive] = it.sensitive - this[Posts.apId] = it.apId - } - UsersFollowers.insert { - it[id] = 100L - it[userId] = userB - it[followerId] = userA - } - } - - val actual = postService.findAll(userId = userA) - assertContentEquals(posts, actual) - } -}