test: Postsのテストを追加

This commit is contained in:
usbharu 2023-05-19 22:54:22 +09:00
parent 050efb1ee0
commit 22ac04a991
8 changed files with 783 additions and 88 deletions

View File

@ -0,0 +1,11 @@
package dev.usbharu.hideout.domain.model.hideout.dto
data class UserResponse(
val id: Long,
val name: String,
val domain: String,
val screenName: String,
val description: String = "",
val url: String,
val createdAt: Long
)

View File

@ -46,7 +46,7 @@ fun Route.posts(postService: IPostService) {
val minId = call.request.queryParameters["minId"]?.toLong() val minId = call.request.queryParameters["minId"]?.toLong()
val maxId = call.request.queryParameters["maxId"]?.toLong() val maxId = call.request.queryParameters["maxId"]?.toLong()
val limit = call.request.queryParameters["limit"]?.toInt() val limit = call.request.queryParameters["limit"]?.toInt()
call.respond(postService.findAll(since, until, minId, maxId, limit, userId)) call.respond(HttpStatusCode.OK, postService.findAll(since, until, minId, maxId, limit, userId))
} }
get("/{id}") { get("/{id}") {
val userId = call.principal<JWTPrincipal>()?.payload?.getClaim("uid")?.asLong() val userId = call.principal<JWTPrincipal>()?.payload?.getClaim("uid")?.asLong()
@ -84,7 +84,6 @@ fun Route.posts(postService: IPostService) {
?: throw ParameterNotExistException("Parameter(name='postsId' does not exist.") ?: throw ParameterNotExistException("Parameter(name='postsId' does not exist.")
val post = (postService.findByIdForUser(id, userId) val post = (postService.findByIdForUser(id, userId)
?: throw PostNotFoundException("$id was not found or is not authorized.")) ?: throw PostNotFoundException("$id was not found or is not authorized."))
call.response.header("Content-Location", post.url)
call.respond(post) call.respond(post)
} }
} }

View File

@ -18,7 +18,7 @@ import io.ktor.server.routing.*
fun Route.users(userService: IUserService) { fun Route.users(userService: IUserService) {
route("/users") { route("/users") {
get { get {
call.respond(userService.findAll()) call.respond(userService.findAllForUser())
} }
post { post {
val userCreate = call.receive<UserCreate>() val userCreate = call.receive<UserCreate>()
@ -34,7 +34,7 @@ fun Route.users(userService: IUserService) {
) )
) )
call.response.header("Location", "${Config.configData.url}/api/internal/v1/users/${user.name}") call.response.header("Location", "${Config.configData.url}/api/internal/v1/users/${user.name}")
call.respond(HttpStatusCode.OK) call.respond(HttpStatusCode.Created)
} }
route("/{name}") { route("/{name}") {

View File

@ -2,12 +2,15 @@ package dev.usbharu.hideout.service.impl
import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto
import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto
import dev.usbharu.hideout.domain.model.hideout.dto.UserResponse
import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.domain.model.hideout.entity.User
@Suppress("TooManyFunctions") @Suppress("TooManyFunctions")
interface IUserService { interface IUserService {
suspend fun findAll(limit: Int? = 100, offset: Long? = 0): List<User> suspend fun findAll(limit: Int? = 100, offset: Long? = 0): List<User>
suspend fun findAllForUser(limit: Int? = 100, offset: Long? = 0): List<UserResponse>
suspend fun findById(id: Long): User suspend fun findById(id: Long): User
suspend fun findByIds(ids: List<Long>): List<User> suspend fun findByIds(ids: List<Long>): List<User>

View File

@ -3,6 +3,7 @@ package dev.usbharu.hideout.service.impl
import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto
import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto
import dev.usbharu.hideout.domain.model.hideout.dto.UserResponse
import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.exception.UserNotFoundException import dev.usbharu.hideout.exception.UserNotFoundException
import dev.usbharu.hideout.repository.IUserRepository import dev.usbharu.hideout.repository.IUserRepository
@ -23,6 +24,10 @@ class UserService(private val userRepository: IUserRepository, private val userA
) )
} }
override suspend fun findAllForUser(limit: Int?, offset: Long?): List<UserResponse> {
TODO("Not yet implemented")
}
override suspend fun findById(id: Long): User = override suspend fun findById(id: Long): User =
userRepository.findById(id) ?: throw UserNotFoundException("$id was not found.") userRepository.findById(id) ?: throw UserNotFoundException("$id was not found.")

View File

@ -1,84 +0,0 @@
package dev.usbharu.hideout.routing.api.internal.v1
import com.auth0.jwt.interfaces.Claim
import com.auth0.jwt.interfaces.Payload
import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.domain.model.hideout.dto.PostCreateDto
import dev.usbharu.hideout.domain.model.hideout.entity.Visibility
import dev.usbharu.hideout.domain.model.hideout.form.Post
import dev.usbharu.hideout.plugins.TOKEN_AUTH
import dev.usbharu.hideout.plugins.configureSerialization
import dev.usbharu.hideout.service.IPostService
import io.ktor.client.request.*
import io.ktor.http.*
import io.ktor.server.auth.*
import io.ktor.server.auth.jwt.*
import io.ktor.server.config.*
import io.ktor.server.routing.*
import io.ktor.server.testing.*
import org.junit.jupiter.api.Test
import org.mockito.kotlin.*
import java.time.Instant
import kotlin.test.assertEquals
class PostsKtTest {
@Test
fun `posts-post postsにpostしたら投稿できる`() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val claim = mock<Claim> {
on { asLong() } doReturn 1234
}
val payload = mock<Payload> {
on { getClaim(eq("uid")) } doReturn claim
}
val postService = mock<IPostService> {
onBlocking { create(any<PostCreateDto>()) } doAnswer {
val argument = it.getArgument<PostCreateDto>(0)
dev.usbharu.hideout.domain.model.hideout.entity.Post(
123L,
argument.userId,
null,
argument.text,
Instant.now().toEpochMilli(),
Visibility.PUBLIC,
"https://example.com"
)
}
}
application {
authentication {
bearer(TOKEN_AUTH) {
authenticate {
println("aaaaaaaaaaaa")
JWTPrincipal(payload)
}
}
}
routing {
route("/api/internal/v1") {
posts(postService)
}
}
configureSerialization()
}
val post = Post("test")
client.post("/api/internal/v1/posts") {
header("Authorization", "Bearer asdkaf")
contentType(ContentType.Application.Json)
setBody(Config.configData.objectMapper.writeValueAsString(post))
}.apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals("https://example.com", headers["Location"])
}
argumentCaptor<PostCreateDto> {
verify(postService).create(capture())
assertEquals(PostCreateDto("test", userId = 1234), firstValue)
}
}
}

View File

@ -0,0 +1,619 @@
package dev.usbharu.hideout.routing.api.internal.v1
import com.auth0.jwt.interfaces.Claim
import com.auth0.jwt.interfaces.Payload
import com.fasterxml.jackson.module.kotlin.readValue
import dev.usbharu.hideout.config.Config
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.plugins.TOKEN_AUTH
import dev.usbharu.hideout.plugins.configureSecurity
import dev.usbharu.hideout.plugins.configureSerialization
import dev.usbharu.hideout.service.IPostService
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.server.auth.*
import io.ktor.server.auth.jwt.*
import io.ktor.server.config.*
import io.ktor.server.routing.*
import io.ktor.server.testing.*
import org.junit.jupiter.api.Test
import org.mockito.kotlin.*
import utils.JsonObjectMapper
import java.time.Instant
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals
class PostsTest {
@Test
fun 認証情報無しでpostsにGETしたらPUBLICな投稿一覧が返ってくる() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val posts = listOf(
Post(
id = 12345,
userId = 4321,
text = "test1",
visibility = Visibility.PUBLIC,
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"
)
)
val postService = mock<IPostService> {
onBlocking {
findAll(
since = anyOrNull(),
until = anyOrNull(),
minId = anyOrNull(),
maxId = anyOrNull(),
limit = anyOrNull(),
userId = isNull()
)
} doReturn posts
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
posts(postService)
}
}
}
client.get("/api/internal/v1/posts").apply {
assertEquals(HttpStatusCode.OK, status)
assertContentEquals(posts, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
}
}
@Test
fun 認証情報ありでpostsにGETすると権限のある投稿が返ってくる() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val claim = mock<Claim> {
on { asLong() } doReturn 1234
}
val payload = mock<Payload> {
on { getClaim(eq("uid")) } doReturn claim
}
val posts = listOf(
Post(
id = 12345,
userId = 4321,
text = "test1",
visibility = Visibility.PUBLIC,
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 = 1234567,
userId = 4333,
text = "Followers only",
visibility = Visibility.FOLLOWERS,
createdAt = Instant.now().toEpochMilli(),
url = "https://example.com/posts/3"
)
)
val postService = mock<IPostService> {
onBlocking {
findAll(
since = anyOrNull(),
until = anyOrNull(),
minId = anyOrNull(),
maxId = anyOrNull(),
limit = anyOrNull(),
userId = isNotNull()
)
} doReturn posts
}
application {
authentication {
bearer(TOKEN_AUTH) {
authenticate {
JWTPrincipal(payload)
}
}
}
configureSerialization()
routing {
route("/api/internal/v1") {
posts(postService)
}
}
}
client.get("/api/internal/v1/posts") {
header("Authorization", "Bearer asdkaf")
}.apply {
assertEquals(HttpStatusCode.OK, status)
}
}
@Test
fun `posts id にGETしたらPUBLICな投稿を取得できる`() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val post = Post(
12345, 1234, text = "aaa", visibility = Visibility.PUBLIC,
createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1"
)
val postService = mock<IPostService> {
onBlocking { findByIdForUser(any(), anyOrNull()) } doReturn post
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
posts(postService)
}
}
}
client.get("/api/internal/v1/posts/1").apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals(post, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
}
}
@Test
fun `認証情報ありでposts id にGETしたら権限のある投稿を取得できる`() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val post = Post(
12345, 1234, text = "aaa", visibility = Visibility.FOLLOWERS,
createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1"
)
val postService = mock<IPostService> {
onBlocking { findByIdForUser(any(), isNotNull()) } doReturn post
}
val claim = mock<Claim> {
on { asLong() } doReturn 1234
}
val payload = mock<Payload> {
on { getClaim(eq("uid")) } doReturn claim
}
application {
configureSerialization()
authentication {
bearer(TOKEN_AUTH) {
authenticate {
JWTPrincipal(payload)
}
}
}
routing {
route("/api/internal/v1") {
posts(postService)
}
}
}
client.get("/api/internal/v1/posts/1") {
header("Authorization", "Bearer asdkaf")
}.apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals(post, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
}
}
@Test
fun `posts-post postsにpostしたら投稿できる`() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val claim = mock<Claim> {
on { asLong() } doReturn 1234
}
val payload = mock<Payload> {
on { getClaim(eq("uid")) } doReturn claim
}
val postService = mock<IPostService> {
onBlocking { create(any<PostCreateDto>()) } doAnswer {
val argument = it.getArgument<PostCreateDto>(0)
Post(
123L,
argument.userId,
null,
argument.text,
Instant.now().toEpochMilli(),
Visibility.PUBLIC,
"https://example.com"
)
}
}
application {
authentication {
bearer(TOKEN_AUTH) {
authenticate {
println("aaaaaaaaaaaa")
JWTPrincipal(payload)
}
}
}
routing {
route("/api/internal/v1") {
posts(postService)
}
}
configureSerialization()
}
val post = dev.usbharu.hideout.domain.model.hideout.form.Post("test")
client.post("/api/internal/v1/posts") {
header("Authorization", "Bearer asdkaf")
contentType(ContentType.Application.Json)
setBody(Config.configData.objectMapper.writeValueAsString(post))
}.apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals("https://example.com", headers["Location"])
}
argumentCaptor<PostCreateDto> {
verify(postService).create(capture())
assertEquals(PostCreateDto("test", userId = 1234), firstValue)
}
}
@Test
fun `users userId postsにGETしたらユーザーのPUBLICな投稿一覧を取得できる`() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val posts = listOf(
Post(
id = 12345,
userId = 1,
text = "test1",
visibility = Visibility.PUBLIC,
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"
)
)
val postService = mock<IPostService> {
onBlocking {
findByUserIdForUser(
userId = any(),
since = anyOrNull(),
until = anyOrNull(),
minId = anyOrNull(),
maxId = anyOrNull(),
limit = anyOrNull(),
forUserId = anyOrNull()
)
} doReturn posts
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
posts(postService)
}
}
}
client.get("/api/internal/v1/users/1/posts").apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals(posts, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
}
}
@Test
fun `users username postsにGETしたらユーザーのPUBLICな投稿一覧を取得できる`() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val posts = listOf(
Post(
id = 12345,
userId = 1,
text = "test1",
visibility = Visibility.PUBLIC,
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"
)
)
val postService = mock<IPostService> {
onBlocking {
findByUserNameAndDomainForUser(
userName = eq("test1"),
domain = eq(Config.configData.domain),
since = anyOrNull(),
until = anyOrNull(),
minId = anyOrNull(),
maxId = anyOrNull(),
limit = anyOrNull(),
forUserId = anyOrNull()
)
} doReturn posts
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
posts(postService)
}
}
}
client.get("/api/internal/v1/users/test1/posts").apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals(posts, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
}
}
@Test
fun `users username@domain postsにGETしたらユーザーのPUBLICな投稿一覧を取得できる`() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val posts = listOf(
Post(
id = 12345,
userId = 1,
text = "test1",
visibility = Visibility.PUBLIC,
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"
)
)
val postService = mock<IPostService> {
onBlocking {
findByUserNameAndDomainForUser(
userName = eq("test1"),
domain = eq("example.com"),
since = anyOrNull(),
until = anyOrNull(),
minId = anyOrNull(),
maxId = anyOrNull(),
limit = anyOrNull(),
forUserId = anyOrNull()
)
} doReturn posts
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
posts(postService)
}
}
}
client.get("/api/internal/v1/users/test1@example.com/posts").apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals(posts, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
}
}
@Test
fun `users @username@domain postsにGETしたらユーザーのPUBLICな投稿一覧を取得できる`() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val posts = listOf(
Post(
id = 12345,
userId = 1,
text = "test1",
visibility = Visibility.PUBLIC,
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"
)
)
val postService = mock<IPostService> {
onBlocking {
findByUserNameAndDomainForUser(
userName = eq("test1"),
domain = eq("example.com"),
since = anyOrNull(),
until = anyOrNull(),
minId = anyOrNull(),
maxId = anyOrNull(),
limit = anyOrNull(),
forUserId = anyOrNull()
)
} doReturn posts
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
posts(postService)
}
}
}
client.get("/api/internal/v1/users/@test1@example.com/posts").apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals(posts, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
}
}
@Test
fun `users name posts id にGETしたらPUBLICな投稿を取得できる`() = testApplication {
environment {
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"
)
val postService = mock<IPostService> {
onBlocking { findByIdForUser(eq(12345L), anyOrNull()) } doReturn post
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
posts(postService)
}
}
}
client.get("/api/internal/v1/users/test/posts/12345").apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals(post, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
}
}
@Test
fun `users id posts id にGETしたらPUBLICな投稿を取得できる`() = testApplication {
environment {
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"
)
val postService = mock<IPostService> {
onBlocking { findByIdForUser(eq(12345L), anyOrNull()) } doReturn post
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
posts(postService)
}
}
}
client.get("/api/internal/v1/users/1/posts/12345").apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals(post, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
}
}
@Test
fun `users name posts id にGETしたらUserIdが間違っててもPUBLICな投稿を取得できる`() = testApplication {
environment {
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"
)
val postService = mock<IPostService> {
onBlocking { findByIdForUser(eq(12345L), anyOrNull()) } doReturn post
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
posts(postService)
}
}
}
client.get("/api/internal/v1/users/423827849732847/posts/12345").apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals(post, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
}
}
@Test
fun `users name posts id にGETしたらuserNameが間違っててもPUBLICな投稿を取得できる`() = testApplication {
environment {
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"
)
val postService = mock<IPostService> {
onBlocking { findByIdForUser(eq(12345L), anyOrNull()) } doReturn post
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
posts(postService)
}
}
}
client.get("/api/internal/v1/users/invalidUserName/posts/12345").apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals(post, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
}
}
}

View File

@ -0,0 +1,142 @@
package dev.usbharu.hideout.routing.api.internal.v1
import com.fasterxml.jackson.module.kotlin.readValue
import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.domain.model.hideout.dto.UserResponse
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.domain.model.hideout.form.UserCreate
import dev.usbharu.hideout.plugins.configureSecurity
import dev.usbharu.hideout.plugins.configureSerialization
import dev.usbharu.hideout.service.impl.IUserService
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.server.config.*
import io.ktor.server.routing.*
import io.ktor.server.testing.*
import org.junit.jupiter.api.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import utils.JsonObjectMapper
import java.time.Instant
import kotlin.test.assertEquals
class UsersTest {
@Test
fun `users にGETするとユーザー一覧を取得できる`() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val users = listOf(
UserResponse(
12345,
"test1",
"example.com",
"test",
"",
"https://example.com/test",
Instant.now().toEpochMilli()
),
UserResponse(
12343,
"tes2",
"example.com",
"test",
"",
"https://example.com/tes2",
Instant.now().toEpochMilli()
),
)
val userService = mock<IUserService> {
onBlocking { findAllForUser(anyOrNull(), anyOrNull()) } doReturn users
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
users(userService)
}
}
}
client.get("/api/internal/v1/users").apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals(users, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
}
}
@Test
fun `users にPOSTすると新規ユーザー作成ができる`() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val userCreateDto = UserCreate("test", "XXXXXXX")
val userService = mock<IUserService> {
onBlocking { usernameAlreadyUse(any()) } doReturn false
onBlocking { createLocalUser(any()) } doReturn User(
id = 12345,
name = "test",
domain = "example.com",
screenName = "testUser",
description = "test user",
password = "XXXXXXX",
inbox = "https://example.com/inbox",
outbox = "https://example.com/outbox",
url = "https://example.com",
publicKey = "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----",
privateKey = "-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----",
createdAt = Instant.now()
)
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
users(userService)
}
}
}
client.post("/api/internal/v1/users") {
contentType(ContentType.Application.Json)
setBody(JsonObjectMapper.objectMapper.writeValueAsString(userCreateDto))
}.apply {
assertEquals(HttpStatusCode.Created, status)
assertEquals(
"${Config.configData.url}/api/internal/v1/users/${userCreateDto.username}",
headers["Location"]
)
}
}
@Test
fun `users 既にユーザー名が使用されているときはBadRequestが帰ってくる`() = testApplication {
environment {
config = ApplicationConfig("empty.conf")
}
val userCreateDto = UserCreate("test", "XXXXXXX")
val userService = mock<IUserService> {
onBlocking { usernameAlreadyUse(any()) } doReturn true
}
application {
configureSerialization()
configureSecurity(mock(), mock(), mock(), mock(), mock())
routing {
route("/api/internal/v1") {
users(userService)
}
}
}
client.post("/api/internal/v1/users") {
contentType(ContentType.Application.Json)
setBody(JsonObjectMapper.objectMapper.writeValueAsString(userCreateDto))
}.apply {
assertEquals(HttpStatusCode.BadRequest, status)
}
}
}