test: ContentTypeRouteSelectorのテストを追加

This commit is contained in:
usbharu 2023-05-05 12:41:04 +09:00
parent d78f5e201f
commit adf5f189dd
Signed by: usbharu
GPG Key ID: 6556747BF94EEBC8
5 changed files with 183 additions and 35 deletions

View File

@ -163,3 +163,11 @@ detekt {
basePath = rootDir.absolutePath basePath = rootDir.absolutePath
autoCorrect = true autoCorrect = true
} }
tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
exclude("**/org/koin/ksp/generated/**")
}
tasks.withType<io.gitlab.arturbosch.detekt.DetektCreateBaselineTask>().configureEach {
exclude("**/org/koin/ksp/generated/**")
}

View File

@ -75,7 +75,7 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo
} }
if (request.headers.contains("Signature")) { if (request.headers.contains("Signature")) {
val all = request.headers.getAll("Signature")!! val all = request.headers.getAll("Signature").orEmpty()
val parameters = mutableListOf<String>() val parameters = mutableListOf<String>()
for (s in all) { for (s in all) {
s.split(",").forEach { parameters.add(it) } s.split(",").forEach { parameters.add(it) }
@ -170,8 +170,12 @@ class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap {
userAuthRepository.findByNameAndDomain( userAuthRepository.findByNameAndDomain(
username, username,
Config.configData.domain Config.configData.domain
)?.publicKey?.replace("-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----")?.replace("", "") )?.run {
?.replace("\n", "") publicKey
.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replace("\n", "")
}
) )
val x509EncodedKeySpec = X509EncodedKeySpec(publicBytes) val x509EncodedKeySpec = X509EncodedKeySpec(publicBytes)
return@runBlocking KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec) return@runBlocking KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec)
@ -184,8 +188,11 @@ class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap {
userAuthRepository.findByNameAndDomain( userAuthRepository.findByNameAndDomain(
username, username,
Config.configData.domain Config.configData.domain
)?.privateKey?.replace("-----BEGIN PRIVATE KEY-----", "")?.replace("-----END PRIVATE KEY-----", "") )?.privateKey?.run {
?.replace("\n", "") replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replace("\n", "")
}
) )
val x509EncodedKeySpec = PKCS8EncodedKeySpec(publicBytes) val x509EncodedKeySpec = PKCS8EncodedKeySpec(publicBytes)
return@runBlocking KeyFactory.getInstance("RSA").generatePrivate(x509EncodedKeySpec) return@runBlocking KeyFactory.getInstance("RSA").generatePrivate(x509EncodedKeySpec)

View File

@ -37,7 +37,7 @@ class ContentTypeRouteSelector(private vararg val contentType: ContentType) : Ro
context.call.application.log.debug("Accept: ${context.call.request.accept()}") context.call.application.log.debug("Accept: ${context.call.request.accept()}")
val requestContentType = context.call.request.accept() ?: return RouteSelectorEvaluation.FailedParameter val requestContentType = context.call.request.accept() ?: return RouteSelectorEvaluation.FailedParameter
return if (requestContentType.split(",") return if (requestContentType.split(",")
.find { contentType.find { contentType -> contentType.match(it) } != null } != null .any { contentType.any { contentType -> contentType.match(it) } }
) { ) {
RouteSelectorEvaluation.Constant RouteSelectorEvaluation.Constant
} else { } else {

View File

@ -279,35 +279,34 @@ class ExposedJobRepository(
private fun ResultRow.toScheduledJob(): ScheduledJob { private fun ResultRow.toScheduledJob(): ScheduledJob {
val single = this val single = this
jobs.run {
return ScheduledJob( return ScheduledJob(
id = single[this.id].value.toString(), id = single[jobs.id].value.toString(),
status = JobStatus.valueOf(single[status]), status = JobStatus.valueOf(single[jobs.status]),
runAt = single[runAt]?.let { Instant.ofEpochMilli(it) }, runAt = single[jobs.runAt]?.let { Instant.ofEpochMilli(it) },
statusMessage = single[statusMessage], statusMessage = single[jobs.statusMessage],
retries = single[retries], retries = single[jobs.retries],
kjobId = single[kjobId]?.let { kjobId = single[jobs.kjobId]?.let {
try { try {
@Suppress("SwallowedException") @Suppress("SwallowedException")
UUID.fromString(it) UUID.fromString(it)
} catch (ignored: IllegalArgumentException) { } catch (ignored: IllegalArgumentException) {
null null
} }
}, },
createdAt = Instant.ofEpochMilli(single[createdAt]), createdAt = Instant.ofEpochMilli(single[jobs.createdAt]),
updatedAt = Instant.ofEpochMilli(single[updatedAt]), updatedAt = Instant.ofEpochMilli(single[jobs.updatedAt]),
settings = JobSettings( settings = JobSettings(
id = single[jobId], id = single[jobs.jobId],
name = single[name], name = single[jobs.name],
properties = single[properties].parseJsonMap() properties = single[jobs.properties].parseJsonMap()
), ),
progress = JobProgress( progress = JobProgress(
step = single[step].toLong(), step = single[jobs.step].toLong(),
max = single[max]?.toLong(), max = single[jobs.max]?.toLong(),
startedAt = single[startedAt]?.let { Instant.ofEpochMilli(it) }, startedAt = single[jobs.startedAt]?.let { Instant.ofEpochMilli(it) },
completedAt = single[completedAt]?.let { Instant.ofEpochMilli(it) } completedAt = single[jobs.completedAt]?.let { Instant.ofEpochMilli(it) }
)
) )
} )
} }
} }

View File

@ -0,0 +1,134 @@
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())
}
}
}