mirror of https://github.com/usbharu/Hideout.git
refactor: Ktorに関連するテストを削除
This commit is contained in:
parent
9b68f1941f
commit
b8e4d2dc3b
|
@ -1,573 +0,0 @@
|
|||
package dev.usbharu.hideout.plugins
|
||||
|
||||
import com.auth0.jwk.Jwk
|
||||
import com.auth0.jwk.JwkProvider
|
||||
import com.auth0.jwt.JWT
|
||||
import com.auth0.jwt.algorithms.Algorithm
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import dev.usbharu.hideout.config.Config
|
||||
import dev.usbharu.hideout.config.ConfigData
|
||||
import dev.usbharu.hideout.domain.model.hideout.dto.JwtToken
|
||||
import dev.usbharu.hideout.domain.model.hideout.entity.Jwt
|
||||
import dev.usbharu.hideout.domain.model.hideout.entity.User
|
||||
import dev.usbharu.hideout.domain.model.hideout.form.RefreshToken
|
||||
import dev.usbharu.hideout.domain.model.hideout.form.UserLogin
|
||||
import dev.usbharu.hideout.exception.InvalidRefreshTokenException
|
||||
import dev.usbharu.hideout.exception.InvalidUsernameOrPasswordException
|
||||
import dev.usbharu.hideout.query.UserQueryService
|
||||
import dev.usbharu.hideout.routing.api.internal.v1.auth
|
||||
import dev.usbharu.hideout.service.api.UserAuthApiService
|
||||
import dev.usbharu.hideout.service.auth.JwtService
|
||||
import dev.usbharu.hideout.service.core.MetaService
|
||||
import dev.usbharu.hideout.service.user.UserAuthService
|
||||
import dev.usbharu.hideout.util.Base64Util
|
||||
import dev.usbharu.hideout.util.JsonWebKeyUtil
|
||||
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.ArgumentMatchers.anyString
|
||||
import org.mockito.kotlin.*
|
||||
import java.security.KeyPairGenerator
|
||||
import java.security.interfaces.RSAPrivateKey
|
||||
import java.security.interfaces.RSAPublicKey
|
||||
import java.time.Instant
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.util.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class SecurityKtTest {
|
||||
@Test
|
||||
fun `login ログイン出来るか`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
Config.configData = ConfigData(url = "http://example.com", objectMapper = jacksonObjectMapper())
|
||||
val jwtToken = JwtToken("Token", "RefreshToken")
|
||||
val userAuthService = mock<UserAuthApiService> {
|
||||
onBlocking { login(eq("testUser"), eq("password")) } doReturn jwtToken
|
||||
}
|
||||
val metaService = mock<MetaService>()
|
||||
val userQueryService = mock<UserQueryService> {
|
||||
onBlocking { findByNameAndDomain(eq("testUser"), eq("example.com")) } doReturn User.of(
|
||||
id = 1L,
|
||||
name = "testUser",
|
||||
domain = "example.com",
|
||||
screenName = "test",
|
||||
description = "",
|
||||
password = "hashedPassword",
|
||||
inbox = "https://example.com/inbox",
|
||||
outbox = "https://example.com/outbox",
|
||||
url = "https://example.com/profile",
|
||||
publicKey = "",
|
||||
privateKey = "",
|
||||
createdAt = Instant.now()
|
||||
)
|
||||
}
|
||||
val jwkProvider = mock<JwkProvider>()
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(jwkProvider, metaService)
|
||||
routing {
|
||||
auth(userAuthService)
|
||||
}
|
||||
}
|
||||
|
||||
client.post("/login") {
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(Config.configData.objectMapper.writeValueAsString(UserLogin("testUser", "password")))
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.OK, call.response.status)
|
||||
assertEquals(jwtToken, Config.configData.objectMapper.readValue(call.response.bodyAsText()))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `login 存在しないユーザーのログインに失敗する`() {
|
||||
testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
Config.configData = ConfigData(url = "http://example.com", objectMapper = jacksonObjectMapper())
|
||||
mock<UserAuthService> {
|
||||
onBlocking { verifyAccount(anyString(), anyString()) }.doReturn(false)
|
||||
}
|
||||
val metaService = mock<MetaService>()
|
||||
mock<UserQueryService>()
|
||||
mock<JwtService>()
|
||||
val jwkProvider = mock<JwkProvider>()
|
||||
val userAuthApiService = mock<UserAuthApiService> {
|
||||
onBlocking { login(anyString(), anyString()) } doThrow InvalidUsernameOrPasswordException()
|
||||
}
|
||||
application {
|
||||
configureStatusPages()
|
||||
configureSerialization()
|
||||
configureSecurity(jwkProvider, metaService)
|
||||
routing {
|
||||
auth(userAuthApiService)
|
||||
}
|
||||
}
|
||||
client.post("/login") {
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(Config.configData.objectMapper.writeValueAsString(UserLogin("InvalidTtestUser", "password")))
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.Unauthorized, call.response.status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `login 不正なパスワードのログインに失敗する`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
Config.configData = ConfigData(url = "http://example.com", objectMapper = jacksonObjectMapper())
|
||||
val metaService = mock<MetaService>()
|
||||
val jwkProvider = mock<JwkProvider>()
|
||||
val userAuthApiService = mock<UserAuthApiService> {
|
||||
onBlocking { login(anyString(), eq("InvalidPassword")) } doThrow InvalidUsernameOrPasswordException()
|
||||
}
|
||||
application {
|
||||
configureStatusPages()
|
||||
configureSerialization()
|
||||
configureSecurity(jwkProvider, metaService)
|
||||
routing {
|
||||
auth(userAuthApiService)
|
||||
}
|
||||
}
|
||||
client.post("/login") {
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(Config.configData.objectMapper.writeValueAsString(UserLogin("TestUser", "InvalidPassword")))
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.Unauthorized, call.response.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `auth-check Authorizedヘッダーが無いと401が帰ってくる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
Config.configData = ConfigData(url = "http://example.com", objectMapper = jacksonObjectMapper())
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
auth(mock())
|
||||
}
|
||||
}
|
||||
client.get("/auth-check").apply {
|
||||
assertEquals(HttpStatusCode.Unauthorized, call.response.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `auth-check Authorizedヘッダーの形式が間違っていると401が帰ってくる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
Config.configData = ConfigData(url = "http://example.com", objectMapper = jacksonObjectMapper())
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
auth(mock())
|
||||
}
|
||||
}
|
||||
client.get("/auth-check") {
|
||||
header("Authorization", "Digest dsfjjhogalkjdfmlhaog")
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.Unauthorized, call.response.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `auth-check Authorizedヘッダーが空だと401が帰ってくる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
Config.configData = ConfigData(url = "http://example.com", objectMapper = jacksonObjectMapper())
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
auth(mock())
|
||||
}
|
||||
}
|
||||
client.get("/auth-check") {
|
||||
header("Authorization", "")
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.Unauthorized, call.response.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `auth-check AuthorizedヘッダーがBeararで空だと401が帰ってくる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
Config.configData = ConfigData(url = "http://example.com", objectMapper = jacksonObjectMapper())
|
||||
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
auth(mock())
|
||||
}
|
||||
}
|
||||
client.get("/auth-check") {
|
||||
header("Authorization", "Bearer ")
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.Unauthorized, call.response.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `auth-check 正当なJWTだとアクセスできる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
|
||||
keyPairGenerator.initialize(2048)
|
||||
val keyPair = keyPairGenerator.generateKeyPair()
|
||||
val rsaPublicKey = keyPair.public as RSAPublicKey
|
||||
|
||||
Config.configData = ConfigData(url = "https://localhost", objectMapper = jacksonObjectMapper())
|
||||
|
||||
val now = Instant.now()
|
||||
val kid = UUID.randomUUID()
|
||||
val token = JWT.create()
|
||||
.withAudience("${Config.configData.url}/users/test")
|
||||
.withIssuer(Config.configData.url)
|
||||
.withKeyId(kid.toString())
|
||||
.withClaim("uid", 123456L)
|
||||
.withExpiresAt(now.plus(30, ChronoUnit.MINUTES))
|
||||
.sign(Algorithm.RSA256(rsaPublicKey, keyPair.private as RSAPrivateKey))
|
||||
val metaService = mock<MetaService> {
|
||||
onBlocking { getJwtMeta() }.doReturn(
|
||||
Jwt(
|
||||
kid,
|
||||
Base64Util.encode(keyPair.private.encoded),
|
||||
Base64Util.encode(rsaPublicKey.encoded)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val readValue = Config.configData.objectMapper.readerFor(Map::class.java)
|
||||
.readValue<MutableMap<String, Any>?>(
|
||||
JsonWebKeyUtil.publicKeyToJwk(
|
||||
rsaPublicKey,
|
||||
kid.toString()
|
||||
)
|
||||
)
|
||||
val jwkProvider = mock<JwkProvider> {
|
||||
onBlocking { get(anyString()) }.doReturn(
|
||||
Jwk.fromValues(
|
||||
(readValue["keys"] as List<Map<String, Any>>)[0]
|
||||
)
|
||||
)
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(jwkProvider, metaService)
|
||||
routing {
|
||||
auth(mock())
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/auth-check") {
|
||||
header("Authorization", "Bearer $token")
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.OK, call.response.status)
|
||||
assertEquals("Hello 123456", call.response.bodyAsText())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `auth-check 期限切れのトークンではアクセスできない`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
|
||||
keyPairGenerator.initialize(2048)
|
||||
val keyPair = keyPairGenerator.generateKeyPair()
|
||||
val rsaPublicKey = keyPair.public as RSAPublicKey
|
||||
|
||||
Config.configData = ConfigData(url = "https://localhost", objectMapper = jacksonObjectMapper())
|
||||
|
||||
val now = Instant.now()
|
||||
val kid = UUID.randomUUID()
|
||||
val token = JWT.create()
|
||||
.withAudience("${Config.configData.url}/users/test")
|
||||
.withIssuer(Config.configData.url)
|
||||
.withKeyId(kid.toString())
|
||||
.withClaim("uid", 123345L)
|
||||
.withExpiresAt(now.minus(30, ChronoUnit.MINUTES))
|
||||
.sign(Algorithm.RSA256(rsaPublicKey, keyPair.private as RSAPrivateKey))
|
||||
val metaService = mock<MetaService> {
|
||||
onBlocking { getJwtMeta() }.doReturn(
|
||||
Jwt(
|
||||
kid,
|
||||
Base64Util.encode(keyPair.private.encoded),
|
||||
Base64Util.encode(rsaPublicKey.encoded)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val readValue = Config.configData.objectMapper.readerFor(Map::class.java)
|
||||
.readValue<MutableMap<String, Any>?>(
|
||||
JsonWebKeyUtil.publicKeyToJwk(
|
||||
rsaPublicKey,
|
||||
kid.toString()
|
||||
)
|
||||
)
|
||||
val jwkProvider = mock<JwkProvider> {
|
||||
onBlocking { get(anyString()) }.doReturn(
|
||||
Jwk.fromValues(
|
||||
(readValue["keys"] as List<Map<String, Any>>)[0]
|
||||
)
|
||||
)
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(jwkProvider, metaService)
|
||||
routing {
|
||||
auth(mock())
|
||||
}
|
||||
}
|
||||
client.get("/auth-check") {
|
||||
header("Authorization", "Bearer $token")
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.Unauthorized, call.response.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `auth-check issuerが間違っているとアクセスできない`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
|
||||
keyPairGenerator.initialize(2048)
|
||||
val keyPair = keyPairGenerator.generateKeyPair()
|
||||
val rsaPublicKey = keyPair.public as RSAPublicKey
|
||||
|
||||
Config.configData = ConfigData(url = "https://localhost", objectMapper = jacksonObjectMapper())
|
||||
|
||||
val now = Instant.now()
|
||||
val kid = UUID.randomUUID()
|
||||
val token = JWT.create()
|
||||
.withAudience("${Config.configData.url}/users/test")
|
||||
.withIssuer("https://example.com")
|
||||
.withKeyId(kid.toString())
|
||||
.withClaim("uid", 12345L)
|
||||
.withExpiresAt(now.plus(30, ChronoUnit.MINUTES))
|
||||
.sign(Algorithm.RSA256(rsaPublicKey, keyPair.private as RSAPrivateKey))
|
||||
val metaService = mock<MetaService> {
|
||||
onBlocking { getJwtMeta() }.doReturn(
|
||||
Jwt(
|
||||
kid,
|
||||
Base64Util.encode(keyPair.private.encoded),
|
||||
Base64Util.encode(rsaPublicKey.encoded)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val readValue = Config.configData.objectMapper.readerFor(Map::class.java)
|
||||
.readValue<MutableMap<String, Any>?>(
|
||||
JsonWebKeyUtil.publicKeyToJwk(
|
||||
rsaPublicKey,
|
||||
kid.toString()
|
||||
)
|
||||
)
|
||||
val jwkProvider = mock<JwkProvider> {
|
||||
onBlocking { get(anyString()) }.doReturn(
|
||||
Jwk.fromValues(
|
||||
(readValue["keys"] as List<Map<String, Any>>)[0]
|
||||
)
|
||||
)
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(jwkProvider, metaService)
|
||||
routing {
|
||||
auth(mock())
|
||||
}
|
||||
}
|
||||
client.get("/auth-check") {
|
||||
header("Authorization", "Bearer $token")
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.Unauthorized, call.response.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `auth-check usernameが空だと失敗する`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
|
||||
keyPairGenerator.initialize(2048)
|
||||
val keyPair = keyPairGenerator.generateKeyPair()
|
||||
val rsaPublicKey = keyPair.public as RSAPublicKey
|
||||
|
||||
Config.configData = ConfigData(url = "https://localhost", objectMapper = jacksonObjectMapper())
|
||||
|
||||
val now = Instant.now()
|
||||
val kid = UUID.randomUUID()
|
||||
val token = JWT.create()
|
||||
.withAudience("${Config.configData.url}/users/test")
|
||||
.withIssuer(Config.configData.url)
|
||||
.withKeyId(kid.toString())
|
||||
.withClaim("uid", null as Long?)
|
||||
.withExpiresAt(now.plus(30, ChronoUnit.MINUTES))
|
||||
.sign(Algorithm.RSA256(rsaPublicKey, keyPair.private as RSAPrivateKey))
|
||||
val metaService = mock<MetaService> {
|
||||
onBlocking { getJwtMeta() }.doReturn(
|
||||
Jwt(
|
||||
kid,
|
||||
Base64Util.encode(keyPair.private.encoded),
|
||||
Base64Util.encode(rsaPublicKey.encoded)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val readValue = Config.configData.objectMapper.readerFor(Map::class.java)
|
||||
.readValue<MutableMap<String, Any>?>(
|
||||
JsonWebKeyUtil.publicKeyToJwk(
|
||||
rsaPublicKey,
|
||||
kid.toString()
|
||||
)
|
||||
)
|
||||
val jwkProvider = mock<JwkProvider> {
|
||||
onBlocking { get(anyString()) }.doReturn(
|
||||
Jwk.fromValues(
|
||||
(readValue["keys"] as List<Map<String, Any>>)[0]
|
||||
)
|
||||
)
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(jwkProvider, metaService)
|
||||
routing {
|
||||
auth(mock())
|
||||
}
|
||||
}
|
||||
client.get("/auth-check") {
|
||||
header("Authorization", "Bearer $token")
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.Unauthorized, call.response.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `auth-check usernameが存在しないと失敗する`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
|
||||
keyPairGenerator.initialize(2048)
|
||||
val keyPair = keyPairGenerator.generateKeyPair()
|
||||
val rsaPublicKey = keyPair.public as RSAPublicKey
|
||||
|
||||
Config.configData = ConfigData(url = "https://localhost", objectMapper = jacksonObjectMapper())
|
||||
|
||||
val now = Instant.now()
|
||||
val kid = UUID.randomUUID()
|
||||
val token = JWT.create()
|
||||
.withAudience("${Config.configData.url}/users/test")
|
||||
.withIssuer(Config.configData.url)
|
||||
.withKeyId(kid.toString())
|
||||
.withExpiresAt(now.plus(30, ChronoUnit.MINUTES))
|
||||
.sign(Algorithm.RSA256(rsaPublicKey, keyPair.private as RSAPrivateKey))
|
||||
val metaService = mock<MetaService> {
|
||||
onBlocking { getJwtMeta() }.doReturn(
|
||||
Jwt(
|
||||
kid,
|
||||
Base64Util.encode(keyPair.private.encoded),
|
||||
Base64Util.encode(rsaPublicKey.encoded)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val readValue = Config.configData.objectMapper.readerFor(Map::class.java)
|
||||
.readValue<MutableMap<String, Any>?>(
|
||||
JsonWebKeyUtil.publicKeyToJwk(
|
||||
rsaPublicKey,
|
||||
kid.toString()
|
||||
)
|
||||
)
|
||||
val jwkProvider = mock<JwkProvider> {
|
||||
onBlocking { get(anyString()) }.doReturn(
|
||||
Jwk.fromValues(
|
||||
(readValue["keys"] as List<Map<String, Any>>)[0]
|
||||
)
|
||||
)
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(jwkProvider, metaService)
|
||||
routing {
|
||||
auth(mock())
|
||||
}
|
||||
}
|
||||
client.get("/auth-check") {
|
||||
header("Authorization", "Bearer $token")
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.Unauthorized, call.response.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `refresh-token リフレッシュトークンが正当だとトークンを発行する`() = testApplication {
|
||||
Config.configData = ConfigData(url = "https://localhost", objectMapper = jacksonObjectMapper())
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val jwtService = mock<UserAuthApiService> {
|
||||
onBlocking { refreshToken(any()) }.doReturn(JwtToken("token", "refreshToken2"))
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
auth(jwtService)
|
||||
}
|
||||
}
|
||||
client.post("/refresh-token") {
|
||||
header("Content-Type", "application/json")
|
||||
setBody(Config.configData.objectMapper.writeValueAsString(RefreshToken("refreshToken")))
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.OK, call.response.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `refresh-token リフレッシュトークンが不正だと失敗する`() = testApplication {
|
||||
Config.configData = ConfigData(url = "https://localhost", objectMapper = jacksonObjectMapper())
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val jwtService = mock<UserAuthApiService> {
|
||||
onBlocking { refreshToken(any()) } doThrow InvalidRefreshTokenException("Invalid Refresh Token")
|
||||
}
|
||||
application {
|
||||
configureStatusPages()
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
auth(jwtService)
|
||||
}
|
||||
}
|
||||
client.post("/refresh-token") {
|
||||
header("Content-Type", "application/json")
|
||||
setBody(Config.configData.objectMapper.writeValueAsString(RefreshToken("InvalidRefreshToken")))
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.BadRequest, call.response.status)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
package dev.usbharu.hideout.routing.activitypub
|
||||
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.statement.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.config.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import io.ktor.server.testing.*
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ContentTypeRouteSelectorTest {
|
||||
@Test
|
||||
fun `Content-Typeが一つでマッチする`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
application {
|
||||
routing {
|
||||
route("/test") {
|
||||
createChild(ContentTypeRouteSelector(ContentType.Application.Json)).handle {
|
||||
call.respondText("OK")
|
||||
}
|
||||
get {
|
||||
call.respondText("NG")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/test") {
|
||||
accept(ContentType.Text.Html)
|
||||
}.apply {
|
||||
assertEquals("NG", bodyAsText())
|
||||
}
|
||||
client.get("/test") {
|
||||
accept(ContentType.Application.Json)
|
||||
}.apply {
|
||||
assertEquals("OK", bodyAsText())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Content-Typeが一つのとき違うとマッチしない`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
application {
|
||||
routing {
|
||||
route("/test") {
|
||||
createChild(ContentTypeRouteSelector(ContentType.Application.Json)).handle {
|
||||
call.respondText("OK")
|
||||
}
|
||||
get {
|
||||
call.respondText("NG")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/test") {
|
||||
accept(ContentType.Text.Html)
|
||||
}.apply {
|
||||
assertEquals("NG", bodyAsText())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Content-Typeがからのときマッチしない`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
application {
|
||||
routing {
|
||||
route("/test") {
|
||||
createChild(ContentTypeRouteSelector()).handle {
|
||||
call.respondText("OK")
|
||||
}
|
||||
get {
|
||||
call.respondText("NG")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/test") {
|
||||
accept(ContentType.Text.Html)
|
||||
}.apply {
|
||||
assertEquals("NG", bodyAsText())
|
||||
}
|
||||
|
||||
client.get("/test").apply {
|
||||
assertEquals("NG", bodyAsText())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Content-Typeが複数指定されていてマッチする`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
application {
|
||||
routing {
|
||||
route("/test") {
|
||||
createChild(ContentTypeRouteSelector(ContentType.Application.Json, ContentType.Text.Html)).handle {
|
||||
call.respondText("OK")
|
||||
}
|
||||
get {
|
||||
call.respondText("NG")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/test") {
|
||||
accept(ContentType.Text.Html)
|
||||
}.apply {
|
||||
assertEquals("OK", bodyAsText())
|
||||
}
|
||||
|
||||
client.get("/test") {
|
||||
accept(ContentType.Application.Json)
|
||||
}.apply {
|
||||
assertEquals("OK", bodyAsText())
|
||||
}
|
||||
client.get("/test") {
|
||||
accept(ContentType.Application.Xml)
|
||||
}.apply {
|
||||
assertEquals("NG", bodyAsText())
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
package dev.usbharu.hideout.routing.activitypub
|
||||
|
||||
import dev.usbharu.hideout.exception.JsonParseException
|
||||
import dev.usbharu.hideout.plugins.configureSerialization
|
||||
import dev.usbharu.hideout.plugins.configureStatusPages
|
||||
import dev.usbharu.hideout.service.ap.APService
|
||||
import dev.usbharu.hideout.service.ap.APUserService
|
||||
import dev.usbharu.hideout.service.auth.HttpSignatureVerifyService
|
||||
import dev.usbharu.hideout.service.user.UserService
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.server.config.*
|
||||
import io.ktor.server.routing.*
|
||||
import io.ktor.server.testing.*
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.doThrow
|
||||
import org.mockito.kotlin.mock
|
||||
|
||||
class InboxRoutingKtTest {
|
||||
@Test
|
||||
fun `sharedInboxにGETしたら405が帰ってくる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
routing {
|
||||
inbox(mock(), mock())
|
||||
}
|
||||
}
|
||||
client.get("/inbox").let {
|
||||
Assertions.assertEquals(HttpStatusCode.MethodNotAllowed, it.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `sharedInboxに空のリクエストボディでPOSTしたら400が帰ってくる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val httpSignatureVerifyService = mock<HttpSignatureVerifyService> {
|
||||
on { verify(any()) } doReturn true
|
||||
}
|
||||
val apService = mock<APService> {
|
||||
on { parseActivity(any()) } doThrow JsonParseException()
|
||||
}
|
||||
mock<UserService>()
|
||||
mock<APUserService>()
|
||||
application {
|
||||
configureStatusPages()
|
||||
configureSerialization()
|
||||
routing {
|
||||
inbox(httpSignatureVerifyService, apService)
|
||||
}
|
||||
}
|
||||
client.post("/inbox").let {
|
||||
Assertions.assertEquals(HttpStatusCode.BadRequest, it.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ユーザのinboxにGETしたら405が帰ってくる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
routing {
|
||||
inbox(mock(), mock())
|
||||
}
|
||||
}
|
||||
client.get("/users/test/inbox").let {
|
||||
Assertions.assertEquals(HttpStatusCode.MethodNotAllowed, it.status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ユーザーのinboxに空のリクエストボディでPOSTしたら400が帰ってくる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val httpSignatureVerifyService = mock<HttpSignatureVerifyService> {
|
||||
on { verify(any()) } doReturn true
|
||||
}
|
||||
val apService = mock<APService> {
|
||||
on { parseActivity(any()) } doThrow JsonParseException()
|
||||
}
|
||||
mock<UserService>()
|
||||
mock<APUserService>()
|
||||
application {
|
||||
configureStatusPages()
|
||||
configureSerialization()
|
||||
routing {
|
||||
inbox(httpSignatureVerifyService, apService)
|
||||
}
|
||||
}
|
||||
client.post("/users/test/inbox").let {
|
||||
Assertions.assertEquals(HttpStatusCode.BadRequest, it.status)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,202 +0,0 @@
|
|||
package dev.usbharu.hideout.routing.activitypub
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude
|
||||
import com.fasterxml.jackson.annotation.JsonSetter
|
||||
import com.fasterxml.jackson.annotation.Nulls
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
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.User
|
||||
import dev.usbharu.hideout.plugins.configureSerialization
|
||||
import dev.usbharu.hideout.query.UserQueryService
|
||||
import dev.usbharu.hideout.service.ap.APUserService
|
||||
import dev.usbharu.hideout.util.HttpUtil.Activity
|
||||
import dev.usbharu.hideout.util.HttpUtil.JsonLd
|
||||
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.ArgumentMatchers.anyString
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.eq
|
||||
import org.mockito.kotlin.mock
|
||||
import utils.TestTransaction
|
||||
import java.time.Instant
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class UsersAPTest {
|
||||
|
||||
@Test()
|
||||
fun `ユーザのURLにAcceptヘッダーをActivityにしてアクセスしたときPersonが返ってくる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val person = Person(
|
||||
type = emptyList(),
|
||||
name = "test",
|
||||
id = "http://example.com/users/test",
|
||||
preferredUsername = "test",
|
||||
summary = "test user",
|
||||
inbox = "http://example.com/users/test/inbox",
|
||||
outbox = "http://example.com/users/test/outbox",
|
||||
url = "http://example.com/users/test",
|
||||
icon = Image(
|
||||
type = emptyList(),
|
||||
name = "http://example.com/users/test/icon.png",
|
||||
mediaType = "image/png",
|
||||
url = "http://example.com/users/test/icon.png"
|
||||
),
|
||||
publicKey = Key(
|
||||
type = emptyList(),
|
||||
name = "Public Key",
|
||||
id = "http://example.com/users/test#pubkey",
|
||||
owner = "https://example.com/users/test",
|
||||
publicKeyPem = "-----BEGIN PUBLIC KEY-----\n\n-----END PUBLIC KEY-----"
|
||||
)
|
||||
)
|
||||
person.context = listOf("https://www.w3.org/ns/activitystreams")
|
||||
|
||||
val apUserService = mock<APUserService> {
|
||||
onBlocking { getPersonByName(anyString()) } doReturn person
|
||||
}
|
||||
|
||||
application {
|
||||
configureSerialization()
|
||||
routing {
|
||||
usersAP(apUserService, mock(), mock(), TestTransaction)
|
||||
}
|
||||
}
|
||||
client.get("/users/test") {
|
||||
accept(ContentType.Application.Activity)
|
||||
}.let {
|
||||
val objectMapper = jacksonObjectMapper().enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
objectMapper.configOverride(List::class.java).setSetterInfo(
|
||||
JsonSetter.Value.forValueNulls(
|
||||
Nulls.AS_EMPTY
|
||||
)
|
||||
)
|
||||
val actual = it.bodyAsText()
|
||||
val readValue = objectMapper.readValue<Person>(actual)
|
||||
assertEquals(person, readValue)
|
||||
}
|
||||
}
|
||||
|
||||
// @Disabled
|
||||
@Test()
|
||||
fun `ユーザのURLにAcceptヘッダーをActivityとJson-LDにしてアクセスしたときPersonが返ってくる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val person = Person(
|
||||
type = emptyList(),
|
||||
name = "test",
|
||||
id = "http://example.com/users/test",
|
||||
preferredUsername = "test",
|
||||
summary = "test user",
|
||||
inbox = "http://example.com/users/test/inbox",
|
||||
outbox = "http://example.com/users/test/outbox",
|
||||
url = "http://example.com/users/test",
|
||||
icon = Image(
|
||||
type = emptyList(),
|
||||
name = "http://example.com/users/test/icon.png",
|
||||
mediaType = "image/png",
|
||||
url = "http://example.com/users/test/icon.png"
|
||||
),
|
||||
publicKey = Key(
|
||||
type = emptyList(),
|
||||
name = "Public Key",
|
||||
id = "http://example.com/users/test#pubkey",
|
||||
owner = "https://example.com/users/test",
|
||||
publicKeyPem = "-----BEGIN PUBLIC KEY-----\n\n-----END PUBLIC KEY-----"
|
||||
)
|
||||
)
|
||||
person.context = listOf("https://www.w3.org/ns/activitystreams")
|
||||
|
||||
val apUserService = mock<APUserService> {
|
||||
onBlocking { getPersonByName(anyString()) } doReturn person
|
||||
}
|
||||
|
||||
application {
|
||||
configureSerialization()
|
||||
routing {
|
||||
usersAP(apUserService, mock(), mock(), TestTransaction)
|
||||
}
|
||||
}
|
||||
client.get("/users/test") {
|
||||
accept(ContentType.Application.JsonLd)
|
||||
accept(ContentType.Application.Activity)
|
||||
}.let {
|
||||
val objectMapper = jacksonObjectMapper().enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
objectMapper.configOverride(List::class.java).setSetterInfo(
|
||||
JsonSetter.Value.forValueNulls(
|
||||
Nulls.AS_EMPTY
|
||||
)
|
||||
)
|
||||
val actual = it.bodyAsText()
|
||||
val readValue = objectMapper.readValue<Person>(actual)
|
||||
assertEquals(person, readValue)
|
||||
}
|
||||
}
|
||||
|
||||
// @Disabled
|
||||
@Test
|
||||
fun contentType_Test() {
|
||||
assertTrue(ContentType.Application.Activity.match("application/activity+json"))
|
||||
val listOf = listOf(ContentType.Application.JsonLd, ContentType.Application.Activity)
|
||||
assertTrue(
|
||||
listOf.find { contentType ->
|
||||
contentType.match("application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")
|
||||
}.let { it != null }
|
||||
)
|
||||
assertTrue(
|
||||
ContentType.Application.JsonLd.match(
|
||||
"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ユーザーのURLにAcceptヘッダーをhtmlにしてアクセスしたときはただの文字を返す() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val userService = mock<UserQueryService> {
|
||||
onBlocking { findByNameAndDomain(eq("test"), anyString()) } doReturn User.of(
|
||||
1L,
|
||||
"test",
|
||||
"example.com",
|
||||
"test",
|
||||
"",
|
||||
"hashedPassword",
|
||||
"https://example.com/inbox",
|
||||
"https://example.com/outbox",
|
||||
"https://example.com",
|
||||
"-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----",
|
||||
Instant.now()
|
||||
)
|
||||
}
|
||||
application {
|
||||
routing {
|
||||
usersAP(mock(), userService, mock(), TestTransaction)
|
||||
}
|
||||
}
|
||||
client.get("/users/test") {
|
||||
accept(ContentType.Text.Html)
|
||||
}.let {
|
||||
assertEquals(HttpStatusCode.OK, it.status)
|
||||
assertTrue(it.contentType()?.match(ContentType.Text.Plain) == true)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,734 +0,0 @@
|
|||
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.PostResponse
|
||||
import dev.usbharu.hideout.domain.model.hideout.dto.UserResponse
|
||||
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.api.PostApiService
|
||||
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 user = UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
)
|
||||
val posts = listOf(
|
||||
PostResponse(
|
||||
id = "12345",
|
||||
user = user,
|
||||
text = "test1",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/1"
|
||||
),
|
||||
PostResponse(
|
||||
id = "123456",
|
||||
user = user,
|
||||
text = "test2",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/2"
|
||||
)
|
||||
)
|
||||
val postService = mock<PostApiService> {
|
||||
onBlocking {
|
||||
getAll(
|
||||
since = anyOrNull(),
|
||||
until = anyOrNull(),
|
||||
minId = anyOrNull(),
|
||||
maxId = anyOrNull(),
|
||||
limit = anyOrNull(),
|
||||
userId = isNull()
|
||||
)
|
||||
} doReturn posts
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(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 user = UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
)
|
||||
val posts = listOf(
|
||||
PostResponse(
|
||||
id = "12345",
|
||||
user = user,
|
||||
text = "test1",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/1"
|
||||
),
|
||||
PostResponse(
|
||||
id = "123456",
|
||||
user = user,
|
||||
text = "test2",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/2"
|
||||
),
|
||||
PostResponse(
|
||||
id = "1234567",
|
||||
user = user,
|
||||
text = "Followers only",
|
||||
visibility = Visibility.FOLLOWERS,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/3"
|
||||
)
|
||||
)
|
||||
|
||||
val postService = mock<PostApiService> {
|
||||
onBlocking {
|
||||
getAll(
|
||||
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 user = UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
)
|
||||
val post = PostResponse(
|
||||
id = "12345",
|
||||
user = user,
|
||||
text = "aaa",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/1"
|
||||
)
|
||||
val postService = mock<PostApiService> {
|
||||
onBlocking { getById(any(), anyOrNull()) } doReturn post
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(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 = PostResponse(
|
||||
"12345",
|
||||
UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
),
|
||||
text = "aaa",
|
||||
visibility = Visibility.FOLLOWERS,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/1"
|
||||
)
|
||||
val postService = mock<PostApiService> {
|
||||
onBlocking { getById(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<PostApiService> {
|
||||
onBlocking { createPost(any(), any()) } doAnswer {
|
||||
val argument = it.getArgument<dev.usbharu.hideout.domain.model.hideout.form.Post>(0)
|
||||
val userId = it.getArgument<Long>(1)
|
||||
PostResponse(
|
||||
id = "123",
|
||||
user = UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
),
|
||||
overview = null,
|
||||
text = argument.text,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
visibility = Visibility.PUBLIC,
|
||||
url = "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<dev.usbharu.hideout.domain.model.hideout.form.Post> {
|
||||
verify(postService).createPost(capture(), any())
|
||||
assertEquals(dev.usbharu.hideout.domain.model.hideout.form.Post("test"), firstValue)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users userId postsにGETしたらユーザーのPUBLICな投稿一覧を取得できる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val user = UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
)
|
||||
val posts = listOf(
|
||||
PostResponse(
|
||||
id = "12345",
|
||||
user = user,
|
||||
text = "test1",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/1"
|
||||
),
|
||||
PostResponse(
|
||||
id = "123456",
|
||||
user = user,
|
||||
text = "test2",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/2"
|
||||
)
|
||||
)
|
||||
val postService = mock<PostApiService> {
|
||||
onBlocking {
|
||||
getByUser(
|
||||
nameOrId = any(),
|
||||
since = anyOrNull(),
|
||||
until = anyOrNull(),
|
||||
minId = anyOrNull(),
|
||||
maxId = anyOrNull(),
|
||||
limit = anyOrNull(),
|
||||
userId = anyOrNull()
|
||||
)
|
||||
} doReturn posts
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(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 user = UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
)
|
||||
val posts = listOf(
|
||||
PostResponse(
|
||||
id = "12345",
|
||||
user = user,
|
||||
text = "test1",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/1"
|
||||
),
|
||||
PostResponse(
|
||||
id = "123456",
|
||||
user = user,
|
||||
text = "test2",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/2"
|
||||
)
|
||||
)
|
||||
val postService = mock<PostApiService> {
|
||||
onBlocking {
|
||||
getByUser(
|
||||
nameOrId = eq("test1"),
|
||||
since = anyOrNull(),
|
||||
until = anyOrNull(),
|
||||
minId = anyOrNull(),
|
||||
maxId = anyOrNull(),
|
||||
limit = anyOrNull(),
|
||||
userId = anyOrNull()
|
||||
)
|
||||
} doReturn posts
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(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 user = UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
)
|
||||
val posts = listOf(
|
||||
PostResponse(
|
||||
id = "12345",
|
||||
user = user,
|
||||
text = "test1",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/1"
|
||||
),
|
||||
PostResponse(
|
||||
id = "123456",
|
||||
user = user,
|
||||
text = "test2",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/2"
|
||||
)
|
||||
)
|
||||
val postService = mock<PostApiService> {
|
||||
onBlocking {
|
||||
getByUser(
|
||||
nameOrId = eq("test1@example.com"),
|
||||
since = anyOrNull(),
|
||||
until = anyOrNull(),
|
||||
minId = anyOrNull(),
|
||||
maxId = anyOrNull(),
|
||||
limit = anyOrNull(),
|
||||
userId = anyOrNull()
|
||||
)
|
||||
} doReturn posts
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(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 user = UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
)
|
||||
val posts = listOf(
|
||||
PostResponse(
|
||||
id = "12345",
|
||||
user = user,
|
||||
text = "test1",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/1"
|
||||
),
|
||||
PostResponse(
|
||||
id = "123456",
|
||||
user = user,
|
||||
text = "test2",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/2"
|
||||
)
|
||||
)
|
||||
val postService = mock<PostApiService> {
|
||||
onBlocking {
|
||||
getByUser(
|
||||
nameOrId = eq("@test1@example.com"),
|
||||
since = anyOrNull(),
|
||||
until = anyOrNull(),
|
||||
minId = anyOrNull(),
|
||||
maxId = anyOrNull(),
|
||||
limit = anyOrNull(),
|
||||
userId = anyOrNull()
|
||||
)
|
||||
} doReturn posts
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(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 = PostResponse(
|
||||
id = "123456",
|
||||
user = UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
),
|
||||
text = "test2",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/2"
|
||||
)
|
||||
val postService = mock<PostApiService> {
|
||||
onBlocking { getById(eq(12345L), anyOrNull()) } doReturn post
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(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 = PostResponse(
|
||||
id = "123456",
|
||||
user = UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
),
|
||||
text = "test2",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/2"
|
||||
)
|
||||
val postService = mock<PostApiService> {
|
||||
onBlocking { getById(eq(12345L), anyOrNull()) } doReturn post
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(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 = PostResponse(
|
||||
id = "123456",
|
||||
user = UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
),
|
||||
text = "test2",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/2"
|
||||
)
|
||||
val postService = mock<PostApiService> {
|
||||
onBlocking { getById(eq(12345L), anyOrNull()) } doReturn post
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(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 = PostResponse(
|
||||
id = "123456",
|
||||
user = UserResponse(
|
||||
id = "54321",
|
||||
name = "user1",
|
||||
domain = "example.com",
|
||||
screenName = "user 1",
|
||||
description = "Test user",
|
||||
url = "https://example.com/users/54321",
|
||||
createdAt = Instant.now().toEpochMilli()
|
||||
),
|
||||
text = "test2",
|
||||
visibility = Visibility.PUBLIC,
|
||||
createdAt = Instant.now().toEpochMilli(),
|
||||
url = "https://example.com/posts/2"
|
||||
)
|
||||
val postService = mock<PostApiService> {
|
||||
onBlocking { getById(eq(12345L), anyOrNull()) } doReturn post
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(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()))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,692 +0,0 @@
|
|||
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.Acct
|
||||
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.TOKEN_AUTH
|
||||
import dev.usbharu.hideout.plugins.configureSecurity
|
||||
import dev.usbharu.hideout.plugins.configureSerialization
|
||||
import dev.usbharu.hideout.service.api.UserApiService
|
||||
import dev.usbharu.hideout.service.user.UserService
|
||||
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.assertEquals
|
||||
@Suppress("LargeClass")
|
||||
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<UserApiService> {
|
||||
onBlocking { findAll(anyOrNull(), anyOrNull()) } doReturn users
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), 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<UserService> {
|
||||
onBlocking { usernameAlreadyUse(any()) } doReturn false
|
||||
onBlocking { createLocalUser(any()) } doReturn User.of(
|
||||
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())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(userService, mock())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<UserService> {
|
||||
onBlocking { usernameAlreadyUse(any()) } doReturn true
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(userService, mock())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.post("/api/internal/v1/users") {
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(JsonObjectMapper.objectMapper.writeValueAsString(userCreateDto))
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.BadRequest, status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users name にGETしたらユーザーを取得できる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val userResponse = UserResponse(
|
||||
"1234",
|
||||
"test1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
val userApiService = mock<UserApiService> {
|
||||
onBlocking { findByAcct(any()) } doReturn userResponse
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/api/internal/v1/users/test1").apply {
|
||||
assertEquals(HttpStatusCode.OK, status)
|
||||
assertEquals(userResponse, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users id にGETしたらユーザーを取得できる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val userResponse = UserResponse(
|
||||
"1234",
|
||||
"test1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
val userApiService = mock<UserApiService> {
|
||||
onBlocking { findById(any()) } doReturn userResponse
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/api/internal/v1/users/1234").apply {
|
||||
assertEquals(HttpStatusCode.OK, status)
|
||||
assertEquals(userResponse, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users name@domain にGETしたらユーザーを取得できる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val userResponse = UserResponse(
|
||||
"1234",
|
||||
"test1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
val userApiService = mock<UserApiService> {
|
||||
onBlocking { findByAcct(any()) } doReturn userResponse
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/api/internal/v1/users/test1").apply {
|
||||
assertEquals(HttpStatusCode.OK, status)
|
||||
assertEquals(userResponse, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users @name@domain にGETしたらユーザーを取得できる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
val userResponse = UserResponse(
|
||||
"1234",
|
||||
"test1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
val userApiService = mock<UserApiService> {
|
||||
onBlocking { findByAcct(any()) } doReturn userResponse
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/api/internal/v1/users/test1").apply {
|
||||
assertEquals(HttpStatusCode.OK, status)
|
||||
assertEquals(userResponse, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users name followers にGETしたらフォロワー一覧を取得できる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
|
||||
val followers = listOf(
|
||||
UserResponse(
|
||||
"1235",
|
||||
"follower1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
),
|
||||
UserResponse(
|
||||
"1236",
|
||||
"follower2",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
)
|
||||
val userApiService = mock<UserApiService> {
|
||||
onBlocking { findFollowersByAcct(any()) } doReturn followers
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/api/internal/v1/users/test1/followers").apply {
|
||||
assertEquals(HttpStatusCode.OK, status)
|
||||
assertEquals(followers, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users name@domain followers にGETしたらフォロワー一覧を取得できる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
|
||||
val followers = listOf(
|
||||
UserResponse(
|
||||
"1235",
|
||||
"follower1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
),
|
||||
UserResponse(
|
||||
"1236",
|
||||
"follower2",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
)
|
||||
val userApiService = mock<UserApiService> {
|
||||
onBlocking { findFollowersByAcct(any()) } doReturn followers
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/api/internal/v1/users/@test1@example.com/followers").apply {
|
||||
assertEquals(HttpStatusCode.OK, status)
|
||||
assertEquals(followers, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users id followers にGETしたらフォロワー一覧を取得できる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
|
||||
val followers = listOf(
|
||||
UserResponse(
|
||||
"1235",
|
||||
"follower1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
),
|
||||
UserResponse(
|
||||
"1236",
|
||||
"follower2",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
)
|
||||
val userApiService = mock<UserApiService> {
|
||||
onBlocking { findFollowers(any()) } doReturn followers
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/api/internal/v1/users/1234/followers").apply {
|
||||
assertEquals(HttpStatusCode.OK, status)
|
||||
assertEquals(followers, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users name followers に認証情報ありで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 userApiService = mock<UserApiService> {
|
||||
onBlocking { findByAcct(any()) } doReturn UserResponse(
|
||||
"1235",
|
||||
"follower1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
onBlocking { follow(any<Acct>(), eq(1234)) } doReturn true
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
authentication {
|
||||
bearer(TOKEN_AUTH) {
|
||||
authenticate {
|
||||
JWTPrincipal(payload)
|
||||
}
|
||||
}
|
||||
}
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.post("/api/internal/v1/users/test1/followers") {
|
||||
header(HttpHeaders.Authorization, "Bearer test")
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.OK, status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users name followers に認証情報ありで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 userApiService = mock<UserApiService> {
|
||||
onBlocking { findByAcct(any()) } doReturn UserResponse(
|
||||
"1235",
|
||||
"follower1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
onBlocking { follow(any<Acct>(), eq(1234)) } doReturn false
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
authentication {
|
||||
bearer(TOKEN_AUTH) {
|
||||
authenticate {
|
||||
JWTPrincipal(payload)
|
||||
}
|
||||
}
|
||||
}
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.post("/api/internal/v1/users/test1/followers") {
|
||||
header(HttpHeaders.Authorization, "Bearer test")
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.Accepted, status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users id followers に認証情報ありで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 userApiService = mock<UserApiService> {
|
||||
onBlocking { findById(any()) } doReturn UserResponse(
|
||||
"1235",
|
||||
"follower1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
onBlocking { follow(eq(1235), eq(1234)) } doReturn false
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
authentication {
|
||||
bearer(TOKEN_AUTH) {
|
||||
authenticate {
|
||||
JWTPrincipal(payload)
|
||||
}
|
||||
}
|
||||
}
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.post("/api/internal/v1/users/1235/followers") {
|
||||
header(HttpHeaders.Authorization, "Bearer test")
|
||||
}.apply {
|
||||
assertEquals(HttpStatusCode.Accepted, status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users name following にGETしたらフォロイー一覧を取得できる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
|
||||
val followers = listOf(
|
||||
UserResponse(
|
||||
"1235",
|
||||
"follower1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
),
|
||||
UserResponse(
|
||||
"1236",
|
||||
"follower2",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
)
|
||||
val userApiService = mock<UserApiService> {
|
||||
onBlocking { findFollowingsByAcct(any()) } doReturn followers
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/api/internal/v1/users/test1/following").apply {
|
||||
assertEquals(HttpStatusCode.OK, status)
|
||||
assertEquals(followers, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users name@domain following にGETしたらフォロイー一覧を取得できる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
|
||||
val followers = listOf(
|
||||
UserResponse(
|
||||
"1235",
|
||||
"follower1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
),
|
||||
UserResponse(
|
||||
"1236",
|
||||
"follower2",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
)
|
||||
val userApiService = mock<UserApiService> {
|
||||
onBlocking { findFollowingsByAcct(any()) } doReturn followers
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/api/internal/v1/users/test1@domain/following").apply {
|
||||
assertEquals(HttpStatusCode.OK, status)
|
||||
assertEquals(followers, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users id following にGETしたらフォロイー一覧を取得できる`() = testApplication {
|
||||
environment {
|
||||
config = ApplicationConfig("empty.conf")
|
||||
}
|
||||
|
||||
val followers = listOf(
|
||||
UserResponse(
|
||||
"1235",
|
||||
"follower1",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
),
|
||||
UserResponse(
|
||||
"1236",
|
||||
"follower2",
|
||||
"example.com",
|
||||
"test",
|
||||
"test User",
|
||||
"https://example.com/test",
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
)
|
||||
val userApiService = mock<UserApiService> {
|
||||
onBlocking { findFollowings(any()) } doReturn followers
|
||||
}
|
||||
application {
|
||||
configureSerialization()
|
||||
configureSecurity(mock(), mock())
|
||||
routing {
|
||||
route("/api/internal/v1") {
|
||||
users(mock(), userApiService)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get("/api/internal/v1/users/1234/following").apply {
|
||||
assertEquals(HttpStatusCode.OK, status)
|
||||
assertEquals(followers, JsonObjectMapper.objectMapper.readValue(bodyAsText()))
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue