diff --git a/gradle.properties b/gradle.properties index 89909840..483b2ee6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,6 @@ org.gradle.parallel=true org.gradle.configureondemand=true org.gradle.caching=true -org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC \ No newline at end of file +org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC --add-opens=java.base/java.util.concurrent.locks=ALL-UNNAMED +org.gradle.configuration-cache=true +org.gradle.configuration-cache.problems=warn \ No newline at end of file diff --git a/hideout-core/build.gradle.kts b/hideout-core/build.gradle.kts index ca9a8cc9..fe0e1d5e 100644 --- a/hideout-core/build.gradle.kts +++ b/hideout-core/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jk1.license.filter.LicenseBundleNormalizer import com.github.jk1.license.importer.DependencyDataImporter import com.github.jk1.license.importer.XmlReportImporter import com.github.jk1.license.render.* -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.kotlin.jvm) @@ -22,58 +22,6 @@ apply { group = "dev.usbharu" version = "0.0.1" -sourceSets { - create("intTest") { - compileClasspath += sourceSets.main.get().output - runtimeClasspath += sourceSets.main.get().output - } - create("e2eTest") { - compileClasspath += sourceSets.main.get().output - runtimeClasspath += sourceSets.main.get().output - } -} - -val intTestImplementation by configurations.getting { - extendsFrom(configurations.implementation.get()) -} -val intTestRuntimeOnly by configurations.getting { - extendsFrom(configurations.runtimeOnly.get()) -} - -val e2eTestImplementation by configurations.getting { - extendsFrom(configurations.implementation.get()) -} - -val e2eTestRuntimeOnly by configurations.getting { - extendsFrom(configurations.runtimeOnly.get()) -} - -val integrationTest = task("integrationTest") { - description = "Runs integration tests." - group = "verification" - - testClassesDirs = sourceSets["intTest"].output.classesDirs - classpath = sourceSets["intTest"].runtimeClasspath - shouldRunAfter("test") - - useJUnitPlatform() -} - -val e2eTest = task("e2eTest") { - description = "Runs e2e tests." - group = "verification" - - testClassesDirs = sourceSets["e2eTest"].output.classesDirs - classpath = sourceSets["e2eTest"].runtimeClasspath - shouldRunAfter("test") - - useJUnitPlatform() -} - -tasks.check { - dependsOn(integrationTest) - dependsOn(e2eTest) -} tasks.withType { useJUnitPlatform() @@ -82,24 +30,20 @@ tasks.withType { "--add-opens", "java.base/java.lang=ALL-UNNAMED", "--add-opens", "java.base/java.util=ALL-UNNAMED", "--add-opens", "java.naming/javax.naming=ALL-UNNAMED", + "--add-opens", "java.base/java.util.concurrent.locks=ALL-UNNAMED" ).toMutableList() } } - -tasks.withType { - kotlinOptions { - freeCompilerArgs += "-Xjsr305=strict" +kotlin { + jvmToolchain(21) + compilerOptions { + freeCompilerArgs.add("-Xjsr305=strict") + jvmTarget = JvmTarget.JVM_21 } -// dependsOn("openApiGenerateMastodonCompatibleApi") -// mustRunAfter("openApiGenerateMastodonCompatibleApi") } -tasks.clean { - delete += listOf("$rootDir/src/main/resources/static") -} - repositories { mavenCentral() maven { @@ -125,21 +69,6 @@ repositories { } } -kotlin { - target { - compilations.all { - kotlinOptions.jvmTarget = JavaVersion.VERSION_21.toString() - } - } -} - -sourceSets.main { - kotlin.srcDirs( - "$buildDir/generated/ksp/main", - "$buildDir/generated/sources/openapi/src/main/kotlin", - "$buildDir/generated/sources/mastodon/src/main/kotlin" - ) -} val os = org.gradle.nativeplatform.platform.internal .DefaultNativePlatform.getCurrentOperatingSystem() @@ -201,30 +130,15 @@ dependencies { testImplementation("org.springframework.boot:spring-boot-starter-test") - implementation(libs.kotlin.junit) - implementation(libs.coroutines.test) - + testImplementation(libs.kotlin.junit) + testImplementation(libs.coroutines.test) testImplementation(libs.ktor.client.mock) testImplementation(libs.h2db) - testImplementation("org.mockito.kotlin:mockito-kotlin:5.3.1") testImplementation("org.mockito:mockito-inline:5.2.0") testImplementation("nl.jqno.equalsverifier:equalsverifier:3.16.1") testImplementation("com.jparams:to-string-verifier:1.4.8") - intTestImplementation("org.springframework.boot:spring-boot-starter-test") - intTestImplementation("org.springframework.security:spring-security-test") - intTestImplementation(libs.kotlin.junit) - intTestImplementation(libs.coroutines.test) - intTestImplementation("org.mockito.kotlin:mockito-kotlin:5.3.1") - intTestImplementation(libs.h2db) - - e2eTestImplementation("org.springframework.boot:spring-boot-starter-test") - e2eTestImplementation("org.springframework.security:spring-security-test") - e2eTestImplementation("org.springframework.boot:spring-boot-starter-webflux") - e2eTestImplementation("com.intuit.karate:karate-junit5:1.4.1") - e2eTestImplementation(libs.h2db) - } detekt { @@ -312,7 +226,9 @@ kover { } springBoot { - buildInfo() + buildInfo { + + } } licenseReport { diff --git a/hideout-core/gradle.properties b/hideout-core/gradle.properties index 29566cd4..f3b8b6f9 100644 --- a/hideout-core/gradle.properties +++ b/hideout-core/gradle.properties @@ -18,3 +18,5 @@ org.gradle.parallel=true org.gradle.configureondemand=true org.gradle.caching=true org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC +org.gradle.configuration-cache=true +org.gradle.configuration-cache.problems=warn \ No newline at end of file diff --git a/hideout-core/src/e2eTest/kotlin/AssertionUtil.kt b/hideout-core/src/e2eTest/kotlin/AssertionUtil.kt deleted file mode 100644 index a93ba706..00000000 --- a/hideout-core/src/e2eTest/kotlin/AssertionUtil.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.selectAll -import java.net.MalformedURLException -import java.net.URL - -object AssertionUtil { - - @JvmStatic - fun assertUserExist(username: String, domain: String): Boolean { - val s = try { - val url = URL(domain) - url.host + ":" + url.port.toString().takeIf { it != "-1" }.orEmpty() - } catch (e: MalformedURLException) { - domain - } - - val selectAll = Actors.selectAll() - println(selectAll.fetchSize) - - println(selectAll.toList().size) - - selectAll.map { "@${it[Actors.name]}@${it[Actors.domain]}" }.forEach { println(it) } - - return Actors.selectAll().where { Actors.name eq username and (Actors.domain eq s) }.empty().not() - } -} diff --git a/hideout-core/src/e2eTest/kotlin/KarateUtil.kt b/hideout-core/src/e2eTest/kotlin/KarateUtil.kt deleted file mode 100644 index 3d2b5604..00000000 --- a/hideout-core/src/e2eTest/kotlin/KarateUtil.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.intuit.karate.junit5.Karate - -object KarateUtil { - fun springBootKarateTest(path: String, scenario: String, clazz: Class<*>, port: String): Karate { - if (scenario.isEmpty()) { - return Karate.run(path).relativeTo(clazz).systemProperty("karate.port", port).karateEnv("dev") - } else { - return Karate.run(path).scenarioName(scenario).relativeTo(clazz).systemProperty("karate.port", port) - .karateEnv("dev") - } - } - - fun e2eTest(path: String, scenario: String = "", properties: Map, clazz: Class<*>): Karate { - val run = Karate.run(path) - - val karate = if (scenario.isEmpty()) { - run - } else { - run.scenarioName(scenario) - } - - var relativeTo = karate.relativeTo(clazz) - - properties.map { relativeTo = relativeTo.systemProperty(it.key, it.value) } - - return relativeTo.karateEnv("dev") - } -} diff --git a/hideout-core/src/e2eTest/kotlin/federation/FollowAcceptTest.kt b/hideout-core/src/e2eTest/kotlin/federation/FollowAcceptTest.kt deleted file mode 100644 index 765556cf..00000000 --- a/hideout-core/src/e2eTest/kotlin/federation/FollowAcceptTest.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package federation - -import AssertionUtil -import KarateUtil -import com.intuit.karate.core.MockServer -import com.intuit.karate.junit5.Karate -import dev.usbharu.hideout.SpringApplication -import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.* -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.test.web.server.LocalServerPort -import org.springframework.transaction.annotation.Transactional -import java.net.MalformedURLException -import java.net.URL - -@SpringBootTest( - classes = [SpringApplication::class], - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT -) -@Transactional -class FollowAcceptTest { - @LocalServerPort - private var port = "" - - @Karate.Test - @TestFactory - @Disabled - fun `FollowAcceptTest`(): Karate { - return KarateUtil.e2eTest( - "FollowAcceptTest", "Follow Accept Test", - mapOf("karate.port" to port), - javaClass - ) - } - - companion object { - lateinit var server: MockServer - - lateinit var _remotePort: String - - @JvmStatic - fun assertUserExist(username: String, domain: String) = runBlocking { - val s = try { - val url = URL(domain) - url.host + ":" + url.port.toString().takeIf { it != "-1" }.orEmpty() - } catch (e: MalformedURLException) { - domain - } - - var check = false - - repeat(10) { - delay(1000) - check = AssertionUtil.assertUserExist(username, s) or check - if (check) { - return@repeat - } - } - - Assertions.assertTrue(check, "User @$username@$s not exist.") - } - - @JvmStatic - fun getRemotePort(): String = _remotePort - - @BeforeAll - @JvmStatic - fun beforeAll(@Autowired flyway: Flyway) { - server = MockServer.feature("classpath:federation/FollowAcceptMockServer.feature").http(0).build() - _remotePort = server.port.toString() - - flyway.clean() - flyway.migrate() - } - - @AfterAll - @JvmStatic - fun afterAll() { - server.stop() - } - } -} diff --git a/hideout-core/src/e2eTest/kotlin/federation/InboxCommonTest.kt b/hideout-core/src/e2eTest/kotlin/federation/InboxCommonTest.kt deleted file mode 100644 index 2e1ece7f..00000000 --- a/hideout-core/src/e2eTest/kotlin/federation/InboxCommonTest.kt +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package federation - -import AssertionUtil -import KarateUtil -import com.intuit.karate.core.MockServer -import com.intuit.karate.junit5.Karate -import dev.usbharu.hideout.SpringApplication -import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.Assertions.assertTrue -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.TestFactory -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.test.web.server.LocalServerPort -import org.springframework.transaction.annotation.Transactional - -@SpringBootTest( - classes = [SpringApplication::class], - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT -) -@Transactional -@Disabled -class InboxCommonTest { - @LocalServerPort - private var port = "" - - @Karate.Test - @TestFactory - fun `inboxにHTTP Signature付きのリクエストがあったらリモートに取得しに行く`(): Karate { - return KarateUtil.e2eTest( - "InboxCommonTest", - "inboxにHTTP Signature付きのリクエストがあったらリモートに取得しに行く", - mapOf( - "karate.port" to port, - "karate.remotePort" to _remotePort - ), - javaClass - ) - } - - @Karate.Test - @TestFactory - fun `user-inboxにHTTP Signature付きのリクエストがあったらリモートに取得しに行く`(): Karate { - return KarateUtil.e2eTest( - "InboxCommonTest", - "user-inboxにHTTP Signature付きのリクエストがあったらリモートに取得しに行く", - mapOf( - "karate.port" to port, - "karate.remotePort" to _remotePort - ), - javaClass - ) - } - - @Karate.Test - @TestFactory - fun `inboxにHTTP Signatureがないリクエストがきたら401を返す`(): Karate { - return KarateUtil.e2eTest( - "InboxCommonTest", - "inboxにHTTP Signatureがないリクエストがきたら401を返す", - mapOf("karate.port" to port), - javaClass - ) - } - - @Karate.Test - @TestFactory - fun `user-inboxにHTTP Signatureがないリクエストがきたら401を返す`(): Karate { - return KarateUtil.e2eTest( - "InboxCommonTest", - "user-inboxにHTTP Signatureがないリクエストがきたら401を返す", - mapOf("karate.port" to port), - javaClass - ) - } - - @Karate.Test - @TestFactory - fun `inboxにConetnt-Type application *+json以外が来たら415を返す`(): Karate { - return KarateUtil.e2eTest( - "InboxCommonTest", - "inboxにContent-Type application/json以外が来たら415を返す", - mapOf("karate.port" to port), - javaClass - ) - } - - companion object { - lateinit var server: MockServer - - lateinit var _remotePort: String - - @JvmStatic - fun assertUserExist(username: String, domain: String) = runBlocking { - var check = false - - repeat(10) { - delay(1000) - check = AssertionUtil.assertUserExist(username, domain) or check - if (check) { - return@repeat - } - } - - assertTrue(check, "User @$username@$domain not exist.") - } - - @JvmStatic - fun getRemotePort(): String = _remotePort - - @BeforeAll - @JvmStatic - fun beforeAll() { - server = MockServer.feature("classpath:federation/InboxxCommonMockServerTest.feature").http(0).build() - _remotePort = server.port.toString() - } - - @AfterAll - @JvmStatic - fun afterAll(@Autowired flyway: Flyway) { - server.stop() - flyway.clean() - flyway.migrate() - } - } -} diff --git a/hideout-core/src/e2eTest/kotlin/oauth2/OAuth2LoginTest.kt b/hideout-core/src/e2eTest/kotlin/oauth2/OAuth2LoginTest.kt deleted file mode 100644 index fd248df1..00000000 --- a/hideout-core/src/e2eTest/kotlin/oauth2/OAuth2LoginTest.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package oauth2 - -import KarateUtil -import com.intuit.karate.junit5.Karate -import dev.usbharu.hideout.SpringApplication -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.TestFactory -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.test.web.server.LocalServerPort -import org.springframework.test.context.jdbc.Sql - -@SpringBootTest( - classes = [SpringApplication::class], - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, -) -@Sql("/oauth2/user.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -class OAuth2LoginTest { - - @LocalServerPort - private var port = "" - - @Karate.Test - @TestFactory - fun `スコープwrite readを持ったトークンの作成`(): Karate { - return KarateUtil.springBootKarateTest( - "Oauth2LoginTest", - "スコープwrite readを持ったトークンの作成", - javaClass, - port - ) - } - - @Karate.Test - @TestFactory - fun `スコープread_statuses write_statusesを持ったトークンの作成`(): Karate { - return KarateUtil.springBootKarateTest( - "Oauth2LoginTest", - "スコープread:statuses write:statusesを持ったトークンの作成", - javaClass, - port - ) - } - - companion object { - @JvmStatic - @AfterAll - fun dropDatabase(@Autowired flyway: Flyway) { - flyway.clean() - flyway.migrate() - } - } -} diff --git a/hideout-core/src/e2eTest/resources/application.yml b/hideout-core/src/e2eTest/resources/application.yml deleted file mode 100644 index 778035ba..00000000 --- a/hideout-core/src/e2eTest/resources/application.yml +++ /dev/null @@ -1,44 +0,0 @@ -hideout: - url: "https://localhost:8080" - use-mongodb: false - security: - jwt: - generate: true - key-id: a - private-key: "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC7VJTUt9Us8cKjMzEfYyjiWA4R4/M2bS1GB4t7NXp98C3SC6dVMvDuictGeurT8jNbvJZHtCSuYEvuNMoSfm76oqFvAp8Gy0iz5sxjZmSnXyCdPEovGhLa0VzMaQ8s+CLOyS56YyCFGeJZqgtzJ6GR3eqoYSW9b9UMvkBpZODSctWSNGj3P7jRFDO5VoTwCQAWbFnOjDfH5Ulgp2PKSQnSJP3AJLQNFNe7br1XbrhV//eO+t51mIpGSDCUv3E0DDFcWDTH9cXDTTlRZVEiR2BwpZOOkE/Z0/BVnhZYL71oZV34bKfWjQIt6V/isSMahdsAASACp4ZTGtwiVuNd9tybAgMBAAECggEBAKTmjaS6tkK8BlPXClTQ2vpz/N6uxDeS35mXpqasqskVlaAidgg/sWqpjXDbXr93otIMLlWsM+X0CqMDgSXKejLS2jx4GDjI1ZTXg++0AMJ8sJ74pWzVDOfmCEQ/7wXs3+cbnXhKriO8Z036q92Qc1+N87SI38nkGa0ABH9CN83HmQqt4fB7UdHzuIRe/me2PGhIq5ZBzj6h3BpoPGzEP+x3l9YmK8t/1cN0pqI+dQwYdgfGjackLu/2qH80MCF7IyQaseZUOJyKrCLtSD/Iixv/hzDEUPfOCjFDgTpzf3cwta8+oE4wHCo1iI1/4TlPkwmXx4qSXtmw4aQPz7IDQvECgYEA8KNThCO2gsC2I9PQDM/8Cw0O983WCDY+oi+7JPiNAJwv5DYBqEZB1QYdj06YD16XlC/HAZMsMku1na2TN0driwenQQWzoev3g2S7gRDoS/FCJSI3jJ+kjgtaA7Qmzlgk1TxODN+G1H91HW7t0l7VnL27IWyYo2qRRK3jzxqUiPUCgYEAx0oQs2reBQGMVZnApD1jeq7n4MvNLcPvt8b/eU9iUv6Y4Mj0Suo/AU8lYZXm8ubbqAlwz2VSVunD2tOplHyMUrtCtObAfVDUAhCndKaA9gApgfb3xw1IKbuQ1u4IF1FJl3VtumfQn//LiH1B3rXhcdyo3/vIttEk48RakUKClU8CgYEAzV7W3COOlDDcQd935DdtKBFRAPRPAlspQUnzMi5eSHMD/ISLDY5IiQHbIH83D4bvXq0X7qQoSBSNP7Dvv3HYuqMhf0DaegrlBuJllFVVq9qPVRnKxt1Il2HgxOBvbhOT+9in1BzA+YJ99UzC85O0Qz06A+CmtHEy4aZ2kj5hHjECgYEAmNS4+A8Fkss8Js1RieK2LniBxMgmYml3pfVLKGnzmng7H2+cwPLhPIzIuwytXywh2bzbsYEfYx3EoEVgMEpPhoarQnYPukrJO4gwE2o5Te6T5mJSZGlQJQj9q4ZB2Dfzet6INsK0oG8XVGXSpQvQh3RUYekCZQkBBFcpqWpbIEsCgYAnM3DQf3FJoSnXaMhrVBIovic5l0xFkEHskAjFTevO86Fsz1C2aSeRKSqGFoOQ0tmJzBEs1R6KqnHInicDTQrKhArgLXX4v3CddjfTRJkFWDbE/CkvKZNOrcf1nhaGCPspRJj2KUkj1Fhl9Cncdn/RsYEONbwQSjIfMPkvxF+8HQ==" - public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u+qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyehkd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdgcKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmwIDAQAB" - storage: - type: local - debug: - trace-query-exception: true - trace-query-call: true - private: false - -spring: - flyway: - enabled: true - clean-disabled: false - datasource: - driver-class-name: org.h2.Driver - url: "jdbc:h2:mem:e2e-test;MODE=POSTGRESQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;CASE_INSENSITIVE_IDENTIFIERS=true;TRACE_LEVEL_FILE=4" - username: "" - password: - data: - mongodb: - auto-index-creation: true - host: localhost - port: 27017 - database: hideout - h2: - console: - enabled: true - -# exposed: -# generate-ddl: true -# excluded-packages: dev.usbharu.hideout.core.infrastructure.kjobexposed -server: - port: 8080 - tomcat: - basedir: tomcat-e2e - accesslog: - enabled: true diff --git a/hideout-core/src/e2eTest/resources/federation/FollowAcceptMockServer.feature b/hideout-core/src/e2eTest/resources/federation/FollowAcceptMockServer.feature deleted file mode 100644 index 60793fde..00000000 --- a/hideout-core/src/e2eTest/resources/federation/FollowAcceptMockServer.feature +++ /dev/null @@ -1,140 +0,0 @@ -Feature: Follow Accept Mock Server - - Background: - * def assertInbox = Java.type(`federation.FollowAcceptTest`) - * def req = {req: []} - - Scenario: pathMatches('/users/test-follower') && methodIs('get') - * def remoteUrl = 'http://localhost:' + assertInbox.getRemotePort() - * def username = 'test-follower' - * def userUrl = remoteUrl + '/users/' + username - - - * def person = - """ - { - "@context": [ - "https://www.w3.org/ns/activitystreams", - "https://w3id.org/security/v1", - { - "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", - "toot": "http://joinmastodon.org/ns#", - "featured": { - "@id": "toot:featured", - "@type": "@id" - }, - "featuredTags": { - "@id": "toot:featuredTags", - "@type": "@id" - }, - "alsoKnownAs": { - "@id": "as:alsoKnownAs", - "@type": "@id" - }, - "movedTo": { - "@id": "as:movedTo", - "@type": "@id" - }, - "schema": "http://schema.org#", - "PropertyValue": "schema:PropertyValue", - "value": "schema:value", - "discoverable": "toot:discoverable", - "Device": "toot:Device", - "Ed25519Signature": "toot:Ed25519Signature", - "Ed25519Key": "toot:Ed25519Key", - "Curve25519Key": "toot:Curve25519Key", - "EncryptedMessage": "toot:EncryptedMessage", - "publicKeyBase64": "toot:publicKeyBase64", - "deviceId": "toot:deviceId", - "claim": { - "@type": "@id", - "@id": "toot:claim" - }, - "fingerprintKey": { - "@type": "@id", - "@id": "toot:fingerprintKey" - }, - "identityKey": { - "@type": "@id", - "@id": "toot:identityKey" - }, - "devices": { - "@type": "@id", - "@id": "toot:devices" - }, - "messageFranking": "toot:messageFranking", - "messageType": "toot:messageType", - "cipherText": "toot:cipherText", - "suspended": "toot:suspended", - "focalPoint": { - "@container": "@list", - "@id": "toot:focalPoint" - } - } - ], - "id": #(userUrl), - "type": "Person", - "following": #(userUrl + '/following'), - "followers": #(userUrl + '/followers'), - "inbox": #(userUrl + '/inbox'), - "outbox": #(userUrl + '/outbox'), - "featured": #(userUrl + '/collections/featured'), - "featuredTags": #(userUrl + '/collections/tags'), - "preferredUsername": #(username), - "name": #(username), - "summary": "E2E Test User Jaga/Cotlin/Winter Boot/Ktol\nYonTude: https://example.com\nY(Tvvitter): https://example.com\n", - "url": #(userUrl + '/@' + username), - "manuallyApprovesFollowers": false, - "discoverable": true, - "published": "2016-03-16T00:00:00Z", - "devices": #(userUrl + '/collections/devices'), - "alsoKnownAs": [ - #( 'https://example.com/users/' + username) - ], - "publicKey": { - "id": #(userUrl + '#main-key'), - "owner": #(userUrl), - "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvmtKo0xYGXR4M0LQQhK4\nBkKpRvvUxrqGV6Ew4CBHSyzdnbFsiBqHUWz4JvRiQvAPqQ4jQFpxVZCPr9xx6lJp\nx7EAAKIdVTnBBV4CYfu7QPsRqtjbB5408q+mo5oUXNs8xg2tcC42p2SJ5CRJX/fr\nOgCZwo3LC9pOBdCQZ+tiiPmWNBTNby99JZn4D/xNcwuhV04qcPoHYD9OPuxxGyzc\naVJ2mqJmvi/lewQuR8qnUIbz+Gik+xvyG6LmyuDoa1H2LDQfQXYb62G70HsYdu7a\ndObvZovytp+kkjP/cUaIYkhhOAYqAA4zCwVRY4NHK0MAMq9sMoUfNJa8U+zR9NvD\noQIDAQAB\n-----END PUBLIC KEY-----\n" - }, - "tag": [], - "attachment": [ - { - "type": "PropertyValue", - "name": "Pixib Fan-Bridge", - "value": "\u003ca href=\"https://example.com/hideout\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"\u003e\u003cspan class=\"invisible\"\u003ehttps://www.\u003c/span\u003e\u003cspan class=\"\"\u003eexample.com/hideout\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e" - }, - { - "type": "PropertyValue", - "name": "GitHub", - "value": "\u003ca href=\"https://github.com/usbharu/hideout\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"\u003e\u003cspan class=\"invisible\"\u003ehttps://\u003c/span\u003e\u003cspan class=\"\"\u003egithub.com/usbharu/hideout\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e" - } - ], - "endpoints": { - "sharedInbox": #(remoteUrl + '/inbox') - }, - "icon": { - "type": "Image", - "mediaType": "image/jpeg", - "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/30/Destroyer_Vozbuzhdenyy.jpg/320px-Destroyer_Vozbuzhdenyy.jpg" - }, - "image": { - "type": "Image", - "mediaType": "image/jpeg", - "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Views_of_Mount_Fuji_from_%C5%8Cwakudani_20211202.jpg/320px-Views_of_Mount_Fuji_from_%C5%8Cwakudani_20211202.jpg" - } -} - """ - - * set req.req[] = '/users/' + username - * def response = person - - Scenario: pathMatches('/inbox') && methodIs('post') - * set req.req[] = '/inbox' - * def responseStatus = 202 - - Scenario: pathMatches('/internal-assertion-api/requests') && methodIs('get') - * def response = req - - Scenario: pathMatches('/internal-assertion-api/requests/deleteAll') && methodIs('post') - * set req.req = [] - * def responseStatus = 200 diff --git a/hideout-core/src/e2eTest/resources/federation/FollowAcceptTest.feature b/hideout-core/src/e2eTest/resources/federation/FollowAcceptTest.feature deleted file mode 100644 index 7cdb39e5..00000000 --- a/hideout-core/src/e2eTest/resources/federation/FollowAcceptTest.feature +++ /dev/null @@ -1,29 +0,0 @@ -Feature: Follow Accept Test - - Background: - * url baseUrl - * def assertionUtil = Java.type('AssertionUtil') - - Scenario: Follow Accept Test - - * def follow = - """ - {"type": "Follow","actor": #(remoteUrl + '/users/test-follower'),"object": #(baseUrl + '/users/test-user')} - """ - - Given path '/inbox' - And header Signature = 'keyId="https://test-hideout.usbharu.dev/users/c#pubkey", algorithm="rsa-sha256", headers="x-request-id tpp-redirect-uri digest psu-id", signature="e/91pFiI5bRffP33EMrqoI5A0xjkg3Ar0kzRGHC/1RsLrDW0zV50dHly/qJJ5xrYHRlss3+vd0mznTLBs1X0hx0uXjpfvCvwclpSi8u+sqn+Y2bcQKzf7ah0vAONQd6zeTYW7e/1kDJreP43PsJyz29KZD16Yop8nM++YeEs6C5eWiyYXKoQozXnfmTOX3y6bhxfKKQWVcxA5aLOTmTZRYTsBsTy9zn8NjDQaRI/0gcyYPqpq+2g8j2DbyJu3Z6zP6VmwbGGlQU/s9Pa7G5LqUPH/sBMSlIeqh+Hvm2pL7B3/BMFvGtTD+e2mR60BFnLIxMYx+oX4o33J2XkFIODLQ=="' - And request follow - When method post - Then status 202 - - And retry until assertionUtil.assertUserExist('test-follower',remoteUrl) - - * url remoteUrl - - Given path '/internal-assertion-api/requests' - When method get - Then status 200 - And match response.req contains ['/users/test-follower'] - - * url baseUrl diff --git a/hideout-core/src/e2eTest/resources/federation/InboxCommonTest.feature b/hideout-core/src/e2eTest/resources/federation/InboxCommonTest.feature deleted file mode 100644 index 848e5630..00000000 --- a/hideout-core/src/e2eTest/resources/federation/InboxCommonTest.feature +++ /dev/null @@ -1,158 +0,0 @@ -Feature: Inbox Common Test - - Background: - * url baseUrl - - Scenario: inboxにHTTP Signature付きのリクエストがあったらリモートに取得しに行く - - * url remoteUrl - - Given path '/internal-assertion-api/requests/deleteAll' - When method post - Then status 200 - - * url baseUrl - - * def inbox = - """ - { "type": "Follow" } - """ - - Given path `/inbox` - And request inbox -# And header Signature = 'keyId="'+ remoteUrl +'/users/test-user#pubkey", algorithm="rsa-sha256", headers="(request-target)", signature="a"' - And header Signature = 'keyId="'+ remoteUrl +'/users/test-user#pubkey", algorithm="rsa-sha256", headers="(request-target) date host digest", signature="FfpkmBogW70FMo94yovGpl15L/m4bDjVIFb9mSZUstPE3H00nHiqNsjAq671qFMJsGOO1uWfLEExcdvzwTiC3wuHShzingvxQUbTgcgRTRZcHbtrOZxT8hYHGndpCXGv/NOLkfXDtZO9v5u0fnA2yJFokzyPHOPJ1cJliWlXP38Bl/pO4H5rBLQBZKpM2jYIjMyI78G2rDXNHEeGrGiyfB5SKb3H6zFQL+X9QpXUI4n0f07VsnwaDyp63oUopmzNUyBEuSqB+8va/lbfcWwrxpZnKGzQRZ+VBcV7jDoKGNOP9/O1xEI2CwB8sh+h6KVHdX3EQEvO1slaaLzcwRRqrQ=="' - When method post - Then status 202 - - * def assertInbox = Java.type(`federation.InboxCommonTest`) - - And assertInbox.assertUserExist('test-user',remoteUrl) - - * url remoteUrl - - Given path '/internal-assertion-api/requests' - When method get - Then status 200 - - * url baseUrl - - * print response - Then match response.req == ['/users/test-user'] - - - Scenario: inboxにHTTP Signatureがないリクエストがきたら401を返す - - * def inbox = - """ - {"type": "Follow"} - """ - - Given path '/inbox' - And request inbox - When method post - Then status 401 - - - Scenario: user-inboxにHTTP Signature付きのリクエストがあったらリモートに取得しに行く - - * url remoteUrl - - Given path '/internal-assertion-api/requests/deleteAll' - When method post - Then status 200 - - * url baseUrl - - * def inbox = - """ - { "type": "Follow" } - """ - - Given path `/inbox` - And request inbox -# And header Signature = 'keyId="'+ remoteUrl +'/users/test-user#pubkey", algorithm="rsa-sha256", headers="(request-target)", signature="a"' - And header Signature = 'keyId="'+ remoteUrl +'/users/test-user2#pubkey", algorithm="rsa-sha256", headers="(request-target) date host digest", signature="FfpkmBogW70FMo94yovGpl15L/m4bDjVIFb9mSZUstPE3H00nHiqNsjAq671qFMJsGOO1uWfLEExcdvzwTiC3wuHShzingvxQUbTgcgRTRZcHbtrOZxT8hYHGndpCXGv/NOLkfXDtZO9v5u0fnA2yJFokzyPHOPJ1cJliWlXP38Bl/pO4H5rBLQBZKpM2jYIjMyI78G2rDXNHEeGrGiyfB5SKb3H6zFQL+X9QpXUI4n0f07VsnwaDyp63oUopmzNUyBEuSqB+8va/lbfcWwrxpZnKGzQRZ+VBcV7jDoKGNOP9/O1xEI2CwB8sh+h6KVHdX3EQEvO1slaaLzcwRRqrQ=="' - When method post - Then status 202 - - * def assertInbox = Java.type(`federation.InboxCommonTest`) - - And assertInbox.assertUserExist('test-user2',remoteUrl) - - - * url remoteUrl - - Given path '/internal-assertion-api/requests' - When method get - Then status 200 - - * url baseUrl - - * print response - Then match response.req == ['/users/test-user2'] - - Scenario: user-inboxにHTTP Signatureがないリクエストがきたら401を返す - - * def inbox = - """ - {"type": "Follow"} - """ - - Given path '/inbox' - And request inbox - When method post - Then status 401 - - - Scenario: inboxにContent-Type application/json以外が来たら415を返す - - * def inbox = - """ - {"type": "Follow"} - """ - - Given path '/inbox' - And request inbox - And header Signature = 'keyId="'+ remoteUrl +'/users/test-user#pubkey", algorithm="rsa-sha256", headers="(request-target) date host digest", signature="FfpkmBogW70FMo94yovGpl15L/m4bDjVIFb9mSZUstPE3H00nHiqNsjAq671qFMJsGOO1uWfLEExcdvzwTiC3wuHShzingvxQUbTgcgRTRZcHbtrOZxT8hYHGndpCXGv/NOLkfXDtZO9v5u0fnA2yJFokzyPHOPJ1cJliWlXP38Bl/pO4H5rBLQBZKpM2jYIjMyI78G2rDXNHEeGrGiyfB5SKb3H6zFQL+X9QpXUI4n0f07VsnwaDyp63oUopmzNUyBEuSqB+8va/lbfcWwrxpZnKGzQRZ+VBcV7jDoKGNOP9/O1xEI2CwB8sh+h6KVHdX3EQEvO1slaaLzcwRRqrQ=="' - And header Accept = 'application/activity+json' - And header Content-Type = 'application/json' - When method post - Then status 202 - - Given path '/inbox' - And request inbox - And header Signature = 'keyId="'+ remoteUrl +'/users/test-user#pubkey", algorithm="rsa-sha256", headers="(request-target) date host digest", signature="FfpkmBogW70FMo94yovGpl15L/m4bDjVIFb9mSZUstPE3H00nHiqNsjAq671qFMJsGOO1uWfLEExcdvzwTiC3wuHShzingvxQUbTgcgRTRZcHbtrOZxT8hYHGndpCXGv/NOLkfXDtZO9v5u0fnA2yJFokzyPHOPJ1cJliWlXP38Bl/pO4H5rBLQBZKpM2jYIjMyI78G2rDXNHEeGrGiyfB5SKb3H6zFQL+X9QpXUI4n0f07VsnwaDyp63oUopmzNUyBEuSqB+8va/lbfcWwrxpZnKGzQRZ+VBcV7jDoKGNOP9/O1xEI2CwB8sh+h6KVHdX3EQEvO1slaaLzcwRRqrQ=="' - And header Accept = 'application/activity+json' - And header Content-Type = 'application/activity+json' - When method post - Then status 202 - - Given path '/inbox' - And request inbox - And header Signature = 'keyId="'+ remoteUrl +'/users/test-user#pubkey", algorithm="rsa-sha256", headers="(request-target) date host digest", signature="FfpkmBogW70FMo94yovGpl15L/m4bDjVIFb9mSZUstPE3H00nHiqNsjAq671qFMJsGOO1uWfLEExcdvzwTiC3wuHShzingvxQUbTgcgRTRZcHbtrOZxT8hYHGndpCXGv/NOLkfXDtZO9v5u0fnA2yJFokzyPHOPJ1cJliWlXP38Bl/pO4H5rBLQBZKpM2jYIjMyI78G2rDXNHEeGrGiyfB5SKb3H6zFQL+X9QpXUI4n0f07VsnwaDyp63oUopmzNUyBEuSqB+8va/lbfcWwrxpZnKGzQRZ+VBcV7jDoKGNOP9/O1xEI2CwB8sh+h6KVHdX3EQEvO1slaaLzcwRRqrQ=="' - And header Accept = 'application/activity+json' - And header Content-Type = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' - When method post - Then status 202 - - Given path '/inbox' - And header Signature = 'keyId="'+ remoteUrl +'/users/test-user#pubkey", algorithm="rsa-sha256", headers="(request-target) date host digest", signature="FfpkmBogW70FMo94yovGpl15L/m4bDjVIFb9mSZUstPE3H00nHiqNsjAq671qFMJsGOO1uWfLEExcdvzwTiC3wuHShzingvxQUbTgcgRTRZcHbtrOZxT8hYHGndpCXGv/NOLkfXDtZO9v5u0fnA2yJFokzyPHOPJ1cJliWlXP38Bl/pO4H5rBLQBZKpM2jYIjMyI78G2rDXNHEeGrGiyfB5SKb3H6zFQL+X9QpXUI4n0f07VsnwaDyp63oUopmzNUyBEuSqB+8va/lbfcWwrxpZnKGzQRZ+VBcV7jDoKGNOP9/O1xEI2CwB8sh+h6KVHdX3EQEvO1slaaLzcwRRqrQ=="' - And header Accept = 'application/activity+json' - When method post - Then status 415 - - * def html = - """ - - - -""" - - Given path '/inbox' - And header Signature = 'keyId="'+ remoteUrl +'/users/test-user#pubkey", algorithm="rsa-sha256", headers="(request-target) date host digest", signature="FfpkmBogW70FMo94yovGpl15L/m4bDjVIFb9mSZUstPE3H00nHiqNsjAq671qFMJsGOO1uWfLEExcdvzwTiC3wuHShzingvxQUbTgcgRTRZcHbtrOZxT8hYHGndpCXGv/NOLkfXDtZO9v5u0fnA2yJFokzyPHOPJ1cJliWlXP38Bl/pO4H5rBLQBZKpM2jYIjMyI78G2rDXNHEeGrGiyfB5SKb3H6zFQL+X9QpXUI4n0f07VsnwaDyp63oUopmzNUyBEuSqB+8va/lbfcWwrxpZnKGzQRZ+VBcV7jDoKGNOP9/O1xEI2CwB8sh+h6KVHdX3EQEvO1slaaLzcwRRqrQ=="' - And header Accept = 'application/activity+json' - And header Content-Type = 'text/html' - And request html - When method post - Then status 415 diff --git a/hideout-core/src/e2eTest/resources/federation/InboxxCommonMockServerTest.feature b/hideout-core/src/e2eTest/resources/federation/InboxxCommonMockServerTest.feature deleted file mode 100644 index 6d114c04..00000000 --- a/hideout-core/src/e2eTest/resources/federation/InboxxCommonMockServerTest.feature +++ /dev/null @@ -1,136 +0,0 @@ -Feature: InboxCommonMockServer - - Background: - * def assertInbox = Java.type(`federation.InboxCommonTest`) - * def req = {req: []} - - Scenario: pathMatches('/users/{username}') && methodIs('get') - * def remoteUrl = 'http://localhost:' + assertInbox.getRemotePort() - * def username = pathParams.username - * def userUrl = remoteUrl + '/users/' + username - - - * def person = - """ -{ - "@context": [ - "https://www.w3.org/ns/activitystreams", - "https://w3id.org/security/v1", - { - "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", - "toot": "http://joinmastodon.org/ns#", - "featured": { - "@id": "toot:featured", - "@type": "@id" - }, - "featuredTags": { - "@id": "toot:featuredTags", - "@type": "@id" - }, - "alsoKnownAs": { - "@id": "as:alsoKnownAs", - "@type": "@id" - }, - "movedTo": { - "@id": "as:movedTo", - "@type": "@id" - }, - "schema": "http://schema.org#", - "PropertyValue": "schema:PropertyValue", - "value": "schema:value", - "discoverable": "toot:discoverable", - "Device": "toot:Device", - "Ed25519Signature": "toot:Ed25519Signature", - "Ed25519Key": "toot:Ed25519Key", - "Curve25519Key": "toot:Curve25519Key", - "EncryptedMessage": "toot:EncryptedMessage", - "publicKeyBase64": "toot:publicKeyBase64", - "deviceId": "toot:deviceId", - "claim": { - "@type": "@id", - "@id": "toot:claim" - }, - "fingerprintKey": { - "@type": "@id", - "@id": "toot:fingerprintKey" - }, - "identityKey": { - "@type": "@id", - "@id": "toot:identityKey" - }, - "devices": { - "@type": "@id", - "@id": "toot:devices" - }, - "messageFranking": "toot:messageFranking", - "messageType": "toot:messageType", - "cipherText": "toot:cipherText", - "suspended": "toot:suspended", - "focalPoint": { - "@container": "@list", - "@id": "toot:focalPoint" - } - } - ], - "id": #(userUrl), - "type": "Person", - "following": #(userUrl + '/following'), - "followers": #(userUrl + '/followers'), - "inbox": #(userUrl + '/inbox'), - "outbox": #(userUrl + '/outbox'), - "featured": #(userUrl + '/collections/featured'), - "featuredTags": #(userUrl + '/collections/tags'), - "preferredUsername": #(username), - "name": #(username), - "summary": "E2E Test User Jaga/Cotlin/Winter Boot/Ktol\nYonTude: https://example.com\nY(Tvvitter): https://example.com\n", - "url": #(userUrl + '/@' + username), - "manuallyApprovesFollowers": false, - "discoverable": true, - "published": "2016-03-16T00:00:00Z", - "devices": #(userUrl + '/collections/devices'), - "alsoKnownAs": [ - #( 'https://example.com/users/' + username) - ], - "publicKey": { - "id": #(userUrl + '#main-key'), - "owner": #(userUrl), - "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvmtKo0xYGXR4M0LQQhK4\nBkKpRvvUxrqGV6Ew4CBHSyzdnbFsiBqHUWz4JvRiQvAPqQ4jQFpxVZCPr9xx6lJp\nx7EAAKIdVTnBBV4CYfu7QPsRqtjbB5408q+mo5oUXNs8xg2tcC42p2SJ5CRJX/fr\nOgCZwo3LC9pOBdCQZ+tiiPmWNBTNby99JZn4D/xNcwuhV04qcPoHYD9OPuxxGyzc\naVJ2mqJmvi/lewQuR8qnUIbz+Gik+xvyG6LmyuDoa1H2LDQfQXYb62G70HsYdu7a\ndObvZovytp+kkjP/cUaIYkhhOAYqAA4zCwVRY4NHK0MAMq9sMoUfNJa8U+zR9NvD\noQIDAQAB\n-----END PUBLIC KEY-----\n" - }, - "tag": [], - "attachment": [ - { - "type": "PropertyValue", - "name": "Pixib Fan-Bridge", - "value": "\u003ca href=\"https://example.com/hideout\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"\u003e\u003cspan class=\"invisible\"\u003ehttps://www.\u003c/span\u003e\u003cspan class=\"\"\u003eexample.com/hideout\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e" - }, - { - "type": "PropertyValue", - "name": "GitHub", - "value": "\u003ca href=\"https://github.com/usbharu/hideout\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"\u003e\u003cspan class=\"invisible\"\u003ehttps://\u003c/span\u003e\u003cspan class=\"\"\u003egithub.com/usbharu/hideout\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e" - } - ], - "endpoints": { - "sharedInbox": #(remoteUrl + '/inbox') - }, - "icon": { - "type": "Image", - "mediaType": "image/jpeg", - "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/30/Destroyer_Vozbuzhdenyy.jpg/320px-Destroyer_Vozbuzhdenyy.jpg" - }, - "image": { - "type": "Image", - "mediaType": "image/jpeg", - "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Views_of_Mount_Fuji_from_%C5%8Cwakudani_20211202.jpg/320px-Views_of_Mount_Fuji_from_%C5%8Cwakudani_20211202.jpg" - } -} - - """ - * set req.req[] = '/users/' + username - * def response = person - - Scenario: pathMatches('/internal-assertion-api/requests') && methodIs('get') - * def response = req - - Scenario: pathMatches('/internal-assertion-api/requests/deleteAll') && methodIs('post') - * set req.req = [] - * def responseStatus = 200 diff --git a/hideout-core/src/e2eTest/resources/karate-config.js b/hideout-core/src/e2eTest/resources/karate-config.js deleted file mode 100644 index a83c2bb4..00000000 --- a/hideout-core/src/e2eTest/resources/karate-config.js +++ /dev/null @@ -1,30 +0,0 @@ -function fn() { - var env = karate.env; // get java system property 'karate.env' - karate.log('karate.env system property was:', env); - if (!env) { - env = 'dev'; // a custom 'intelligent' default - karate.log('karate.env set to "dev" as default.'); - } - let config; - if (env === 'test') { - let remotePort = karate.properties['karate.remotePort'] || '8081' - config = { - baseUrl: 'https://test-hideout.usbharu.dev', - remoteUrl: 'http://localhost:' + remotePort - } - } else if (env === 'dev') { - let port = karate.properties['karate.port'] || '8080' - let remotePort = karate.properties['karate.remotePort'] || '8081' - config = { - baseUrl: 'http://localhost:' + port, - remoteUrl: 'http://localhost:' + remotePort - } - } else { - throw 'Unknown environment [' + env + '].' - } - // don't waste time waiting for a connection or if servers don't respond within 0,3 seconds - - karate.configure('connectTimeout', 1000); - karate.configure('readTimeout', 1000); - return config; -} diff --git a/hideout-core/src/e2eTest/resources/logback.xml b/hideout-core/src/e2eTest/resources/logback.xml deleted file mode 100644 index c21752ee..00000000 --- a/hideout-core/src/e2eTest/resources/logback.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - ./e2eTest.log - - UTF-8 - %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{x-request-id}] %logger{36} - %msg%n - - - - - %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{x-request-id}] %logger{36} - %msg%n - - - - - - - - - - diff --git a/hideout-core/src/e2eTest/resources/oauth2/Oauth2LoginTest.feature b/hideout-core/src/e2eTest/resources/oauth2/Oauth2LoginTest.feature deleted file mode 100644 index af203344..00000000 --- a/hideout-core/src/e2eTest/resources/oauth2/Oauth2LoginTest.feature +++ /dev/null @@ -1,95 +0,0 @@ -Feature: OAuth2 Login Test - - Background: - * url baseUrl - * configure driver = { type: 'chrome',start: true, headless: true, showDriverLog: true, addOptions: [ '--headless=new' ] } - - Scenario: スコープwrite readを持ったトークンの作成 - - * def apps = - """ - { - "client_name": "oauth2-test-client-1", - "redirect_uris": "https://usbharu.dev", - "scopes": "write read" - } - """ - - Given path '/api/v1/apps' - And request apps - When method post - Then status 200 - - * def client_id = response.client_id - * def client_secret = response.client_secret - - * def authorizeEndpoint = baseUrl + '/oauth/authorize?response_type=code&redirect_uri=https://usbharu.dev&client_id=' + client_id + '&scope=write%20read' - - Given driver authorizeEndpoint - And driver.input('#username','test-user') - And driver.input('#password','password') - - When driver.submit().click('body > div > form > button') - Then driver.waitForUrl(authorizeEndpoint + "&continue") - And driver.click('#read') - And driver.click('#write') - - When driver.submit().click('#submit-consent') - Then driver.waitUntil("location.host == 'usbharu.dev'") - - * def code = script("new URLSearchParams(document.location.search).get('code')") - - Given path '/oauth/token' - And form field client_id = client_id - And form field client_secret = client_secret - And form field redirect_uri = 'https://usbharu.dev' - And form field grant_type = 'authorization_code' - And form field code = code - And form field scope = 'write read' - When method post - Then status 200 - - Scenario: スコープread:statuses write:statusesを持ったトークンの作成 - - * def apps = - """ - { - "client_name": "oauth2-test-client-2", - "redirect_uris": "https://usbharu.dev", - "scopes": "read:statuses write:statuses" - } - """ - - Given path '/api/v1/apps' - And request apps - When method post - Then status 200 - - * def client_id = response.client_id - * def client_secret = response.client_secret - - * def authorizeEndpoint = baseUrl + '/oauth/authorize?response_type=code&redirect_uri=https://usbharu.dev&client_id=' + client_id + '&scope=read:statuses+write:statuses' - - Given driver authorizeEndpoint - And driver.input('#username','test-user') - And driver.input('#password','password') - - When driver.submit().click('body > div > form > button') - Then driver.waitForUrl(authorizeEndpoint + "&continue") - And driver.click('/html/body/div/div[4]/div/form/div[1]/input') - And driver.click('/html/body/div/div[4]/div/form/div[2]/input') - - When driver.submit().click('#submit-consent') - Then driver.waitUntil("location.host == 'usbharu.dev'") - - * def code = script("new URLSearchParams(document.location.search).get('code')") - - Given path '/oauth/token' - And form field client_id = client_id - And form field client_secret = client_secret - And form field redirect_uri = 'https://usbharu.dev' - And form field grant_type = 'authorization_code' - And form field code = code - And form field scope = 'write read' - When method post - Then status 200 diff --git a/hideout-core/src/e2eTest/resources/oauth2/user.sql b/hideout-core/src/e2eTest/resources/oauth2/user.sql deleted file mode 100644 index 4184f284..00000000 --- a/hideout-core/src/e2eTest/resources/oauth2/user.sql +++ /dev/null @@ -1,51 +0,0 @@ -insert into actors (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, created_at, - key_id, following, followers, instance, locked, following_count, followers_count, posts_count, - last_post_at) -VALUES (1730415786666758144, 'test-user', 'localhost', 'Im test user.', 'THis account is test user.', - 'http://localhost/users/test-user/inbox', - 'http://localhost/users/test-user/outbox', 'http://localhost/users/test-user', - '-----BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi4mifRg6huAIn6DXk3Vn -5tkRC0AO32ZJvczwXr9xDj4HJvrSUHBAxIwwIeuCceAYtiuZk4JmEKydeB6SRkoO -Nty93XZXS1SMmiHCvWOY5YlpnfFU1kLqW3fkXcLNls4XmzujLt1i2sT8mYkENAsP -h6K4SRtmktOVYZOWcVEcfLGKbJvaDD/+lKikNC1XCouylfGV/bA/FPY5vuI+7cdM -Mjana28JdiWlPWSdzcxtCSgN+nGWPjk2WWm8K+wK2zXqMxA0U0p4odyyILBGALxX -zMqObIQvpwPh/t+b6ohem4eq70/0/SwDhd+IzHkT3x4UzG1oxSQS/juPkO7uuS8p -uwIDAQAB ------END PUBLIC KEY----- -', - '-----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCLiaJ9GDqG4Aif -oNeTdWfm2RELQA7fZkm9zPBev3EOPgcm+tJQcEDEjDAh64Jx4Bi2K5mTgmYQrJ14 -HpJGSg423L3ddldLVIyaIcK9Y5jliWmd8VTWQupbd+Rdws2WzhebO6Mu3WLaxPyZ -iQQ0Cw+HorhJG2aS05Vhk5ZxURx8sYpsm9oMP/6UqKQ0LVcKi7KV8ZX9sD8U9jm+ -4j7tx0wyNqdrbwl2JaU9ZJ3NzG0JKA36cZY+OTZZabwr7ArbNeozEDRTSnih3LIg -sEYAvFfMyo5shC+nA+H+35vqiF6bh6rvT/T9LAOF34jMeRPfHhTMbWjFJBL+O4+Q -7u65Lym7AgMBAAECggEADJLa7v3LbFLsxAGY22NFeRJPTF252VycwXshn9ANbnSd -bWBFqlTrKSrevXe82ekRIP09ygKCkvcS+3t5v9a1gDEU9MtQo2ubfdoT87/xS6G9 -wCs6c1I1Twe3LtG6d9/bVbQiiLsPSNpeTrF/jPcAL780bvYGoK1rNQ85C7383Kl6 -1nwZCD0itjkmzbO0nGMRCduW46OdQKiOMuEC7z0zwynH3cK3wGvdlKyLG4L3pPZm -1/Uz7AZTieqSCjSgcgmaut7dmS49e3j8ujfb3wcKscfHoofyqNWsW1xyU1WytO9a -QLh9wlqfvGlfwQWkY6z6uFmc4XfRVZSC8nic4cAW3QKBgQC4PYbR5AuylDcfc6Am -jpL5mcF6qEMnEPgnL9z5VvuLs1f/JEyx5VgzQreDOKc1KOxDX7Xhok4gpvIJv1fi -zimviszEmIpHdPvgS7mP2hu42bSIjwVaXpny5aEEZbB6HQ9pGDW/MSsgmb6x31Kx -o+sslpqf9cpalI35UPtkNaEJNwKBgQDB4tVUQ5gGPKllEfCN64B/B7wodWr5cUNU -UpUXdFPCu+HXnRen6GKLo+25wmCUGtcIuvCY1Xm+tL0Z7jrI+oOD4CL9ob7BJrPF -XCq0jUhaEzWFGp1SOa6n+35fWPkCfG4EwfsK8+PWoZsZc1eykMxIJmBln3vufuHz -qybfhy0VnQKBgD2tAxvyXmQar9VMjLk7k0IRUa6w80H5sUjVAgFKOA0NLZEQ4sfO -wdbvJ6W66mamW2k2ehmdjs/pcy8GKfKYF2ZXbbMGaYwAQm1UjDr2xb78yi3Iyv70 -mk6wxlVFgW1vmwAQhbWKTSitryO2YeVrvUeA5yRTULk/78Mdc/qY5V7DAoGAAu3I -RzOWMlHsRSiWN66dDE4zm3DaotYBLF7q/aW2NjTcXoNy/ghWpMFfL/UtvE8DfJBG -XiirZCQazy94F90g63cRUD+HQCezg4G2629O7n1ny5DxW3Kfns3/xLT1XgI/Lzc2 -8Z1pja53R1Ukt//T9isOPbrBBoNIKoQlXC8QkUkCgYEAsib3uOMAIOJab5jc8FSj -VG+Cg2H63J5DgUUwx2Y0DPENugdGyYzCDMVPBNaB0Ru1SpqbUjgqh+YHynunSVeu -hDXMOteeyeVHUGw8mvcCEt53uRYVNW/rzXTMqfLVxbsJZHCsJBtFpwcgD2w4NjS2 -Ja15+ZWbOA4vJA9pOh3x4XM= ------END PRIVATE KEY----- -', 1701398248417, - 'http://localhost/users/test-user#pubkey', 'http://localhost/users/test-user/following', - 'http://localhost/users/test-users/followers', 0, false, 0, 0, 0, null); - -insert into user_details (actor_id, password, auto_accept_followee_follow_request) -values ( 1730415786666758144 - , '$2a$10$/mWC/n7nC7X3l9qCEOKnredxne2zewoqEsJWTOdlKfg2zXKJ0F9Em', true) diff --git a/hideout-core/src/intTest/kotlin/activitypub/inbox/InboxTest.kt b/hideout-core/src/intTest/kotlin/activitypub/inbox/InboxTest.kt deleted file mode 100644 index 40f9ffdf..00000000 --- a/hideout-core/src/intTest/kotlin/activitypub/inbox/InboxTest.kt +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package activitypub.inbox - -import dev.usbharu.hideout.SpringApplication -import dev.usbharu.hideout.util.Base64Util -import dev.usbharu.owl.producer.api.OwlProducer -import kotlinx.coroutines.runBlocking -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.test.context.TestConfiguration -import org.springframework.context.annotation.Bean -import org.springframework.http.MediaType -import org.springframework.security.test.context.support.WithAnonymousUser -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.post -import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.context.WebApplicationContext -import util.TestTransaction -import util.WithMockHttpSignature -import java.security.MessageDigest -import java.time.ZonedDateTime -import java.time.format.DateTimeFormatter - -@SpringBootTest(classes = [SpringApplication::class]) -@AutoConfigureMockMvc -@Transactional -class InboxTest { - - @Autowired - @Qualifier("http") - private lateinit var dateTimeFormatter: DateTimeFormatter - - @Autowired - private lateinit var context: WebApplicationContext - - private lateinit var mockMvc: MockMvc - - - @BeforeEach - fun setUp() { - mockMvc = MockMvcBuilders.webAppContextSetup(context) - .apply(springSecurity()) - .build() - } - - @Test - @WithAnonymousUser - fun `匿名でinboxにPOSTしたら401`() { - mockMvc - .post("/inbox") { - content = "{}" - contentType = MediaType.APPLICATION_JSON - header("Host", "example.com") - header("Date", ZonedDateTime.now().format(dateTimeFormatter)) - header( - "Digest", - "SHA-256=" + Base64Util.encode(MessageDigest.getInstance("SHA-256").digest("{}".toByteArray())) - ) - } - .asyncDispatch() - .andExpect { status { isUnauthorized() } } - } - - @Test - @WithMockHttpSignature - fun 有効なHttpSignatureでPOSTしたら202() { - mockMvc - .post("/inbox") { - content = "{}" - contentType = MediaType.APPLICATION_JSON - header("Signature", "a") - header("Host", "example.com") - header("Date", ZonedDateTime.now().format(dateTimeFormatter)) - header( - "Digest", - "SHA-256=" + Base64Util.encode(MessageDigest.getInstance("SHA-256").digest("{}".toByteArray())) - ) - } - .asyncDispatch() - .andExpect { status { isAccepted() } } - } - - @Test - @WithAnonymousUser - fun `匿名でuser-inboxにPOSTしたら401`() { - mockMvc - .post("/users/hoge/inbox") { - content = "{}" - contentType = MediaType.APPLICATION_JSON - header("Host", "example.com") - header("Date", ZonedDateTime.now().format(dateTimeFormatter)) - header( - "Digest", - "SHA-256=" + Base64Util.encode(MessageDigest.getInstance("SHA-256").digest("{}".toByteArray())) - ) - } - .asyncDispatch() - .andDo { print() } - .andExpect { status { isUnauthorized() } } - } - - @Test - @WithMockHttpSignature - fun 有効なHttpSignaturesでPOSTしたら202() { - mockMvc - .post("/users/hoge/inbox") { - content = "{}" - contentType = MediaType.APPLICATION_JSON - header("Signature", "a") - header("Host", "example.com") - header("Date", ZonedDateTime.now().format(dateTimeFormatter)) - header( - "Digest", - "SHA-256=" + Base64Util.encode(MessageDigest.getInstance("SHA-256").digest("{}".toByteArray())) - ) - } - .asyncDispatch() - .andDo { print() } - .andExpect { status { isAccepted() } } - } - - @TestConfiguration - class Configuration { - @Bean - fun testTransaction() = TestTransaction - } - - companion object { - @JvmStatic - @AfterAll - fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { - flyway.clean() - flyway.migrate() - runBlocking { - owlProducer.stop() - } - } - } -} diff --git a/hideout-core/src/intTest/kotlin/activitypub/note/NoteTest.kt b/hideout-core/src/intTest/kotlin/activitypub/note/NoteTest.kt deleted file mode 100644 index 62d7d3ce..00000000 --- a/hideout-core/src/intTest/kotlin/activitypub/note/NoteTest.kt +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package activitypub.note - -import dev.usbharu.hideout.SpringApplication -import dev.usbharu.owl.producer.api.OwlProducer -import kotlinx.coroutines.runBlocking -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.http.MediaType -import org.springframework.security.test.context.support.WithAnonymousUser -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity -import org.springframework.test.context.jdbc.Sql -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.get -import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.context.WebApplicationContext -import util.WithHttpSignature -import util.WithMockHttpSignature -import java.time.ZonedDateTime -import java.time.format.DateTimeFormatter - -@SpringBootTest(classes = [SpringApplication::class]) -@AutoConfigureMockMvc -@Transactional -class NoteTest { - private lateinit var mockMvc: MockMvc - - @Autowired - private lateinit var context: WebApplicationContext - - @Autowired - @Qualifier("http") - private lateinit var dateTimeFormatter: DateTimeFormatter - - @BeforeEach - fun setUp() { - mockMvc = MockMvcBuilders.webAppContextSetup(context).apply(springSecurity()).build() - } - - @Test - @WithAnonymousUser - @Sql("/sql/note/匿名でpublic投稿を取得できる.sql") - fun `匿名でpublic投稿を取得できる`() { - mockMvc - .get("/users/test-user/posts/1234") { - accept(MediaType("application", "activity+json")) - } - .asyncDispatch() - .andDo { print() } - .andExpect { status { isOk() } } - .andExpect { content { contentType("application/activity+json") } } - .andExpect { jsonPath("\$.type") { value("Note") } } - .andExpect { jsonPath("\$.to") { value("https://www.w3.org/ns/activitystreams#Public") } } - .andExpect { jsonPath("\$.cc") { value("https://www.w3.org/ns/activitystreams#Public") } } - } - - @Test - @Sql("/sql/note/匿名でunlisted投稿を取得できる.sql") - @WithAnonymousUser - fun 匿名でunlisted投稿を取得できる() { - mockMvc - .get("/users/test-user2/posts/1235") { - accept(MediaType("application", "activity+json")) - } - .asyncDispatch() - .andDo { print() } - .andExpect { status { isOk() } } - .andExpect { content { contentType("application/activity+json") } } - .andExpect { jsonPath("\$.type") { value("Note") } } - .andExpect { jsonPath("\$.to") { value("https://example.com/users/test-user2/followers") } } - .andExpect { jsonPath("\$.cc") { value("https://www.w3.org/ns/activitystreams#Public") } } - } - - @Test - @Transactional - @WithAnonymousUser - @Sql("/sql/note/匿名でfollowers投稿を取得しようとすると404.sql") - fun 匿名でfollowers投稿を取得しようとすると404() { - mockMvc - .get("/users/test-user2/posts/1236") { - accept(MediaType("application", "activity+json")) - } - .asyncDispatch() - .andExpect { status { isNotFound() } } - } - - @Test - @WithAnonymousUser - fun 匿名でdirect投稿を取得しようとすると404() { - mockMvc - .get("/users/test-user2/posts/1236") { - accept(MediaType("application", "activity+json")) - } - .asyncDispatch() - .andExpect { status { isNotFound() } } - } - - @Test - @Sql("/sql/note/httpSignature認証でフォロワーがpublic投稿を取得できる.sql") - @WithHttpSignature(keyId = "https://follower.example.com/users/test-user5#pubkey") - fun HttpSignature認証でフォロワーがpublic投稿を取得できる() { - mockMvc - .get("/users/test-user4/posts/1237") { - accept(MediaType("application", "activity+json")) - } - .asyncDispatch() - .andDo { print() } - .andExpect { status { isOk() } } - .andExpect { content { contentType("application/activity+json") } } - .andExpect { jsonPath("\$.type") { value("Note") } } - .andExpect { jsonPath("\$.to") { value("https://www.w3.org/ns/activitystreams#Public") } } - .andExpect { jsonPath("\$.cc") { value("https://www.w3.org/ns/activitystreams#Public") } } - } - - @Test - @Sql("/sql/note/httpSignature認証でフォロワーがunlisted投稿を取得できる.sql") - @WithHttpSignature(keyId = "https://follower.example.com/users/test-user7#pubkey") - fun httpSignature認証でフォロワーがunlisted投稿を取得できる() { - mockMvc - .get("/users/test-user6/posts/1238") { - accept(MediaType("application", "activity+json")) - } - .asyncDispatch() - .andDo { print() } - .andExpect { status { isOk() } } - .andExpect { content { contentType("application/activity+json") } } - .andExpect { jsonPath("\$.type") { value("Note") } } - .andExpect { jsonPath("\$.to") { value("https://example.com/users/test-user6/followers") } } - .andExpect { jsonPath("\$.cc") { value("https://www.w3.org/ns/activitystreams#Public") } } - } - - @Test - @Sql("/sql/note/httpSignature認証でフォロワーがfollowers投稿を取得できる.sql") - @WithHttpSignature(keyId = "https://follower.example.com/users/test-user9#pubkey") - fun httpSignature認証でフォロワーがfollowers投稿を取得できる() { - mockMvc - .get("/users/test-user8/posts/1239") { - accept(MediaType("application", "activity+json")) - } - .asyncDispatch() - .andDo { print() } - .andExpect { status { isOk() } } - .andExpect { content { contentType("application/activity+json") } } - .andExpect { jsonPath("\$.type") { value("Note") } } - .andExpect { jsonPath("\$.to") { value("https://example.com/users/test-user8/followers") } } - .andExpect { jsonPath("\$.cc") { value("https://example.com/users/test-user8/followers") } } - - } - - @Test - @Sql("/sql/note/リプライになっている投稿はinReplyToが存在する.sql") - @WithMockHttpSignature - fun リプライになっている投稿はinReplyToが存在する() { - mockMvc - .get("/users/test-user10/posts/1241") { - accept(MediaType("application", "activity+json")) - } - .asyncDispatch() - .andDo { print() } - .andExpect { status { isOk() } } - .andExpect { content { contentType("application/activity+json") } } - .andExpect { jsonPath("\$.type") { value("Note") } } - .andExpect { jsonPath("\$.inReplyTo") { value("https://example.com/users/test-user10/posts/1240") } } - } - - @Test - @Sql("/sql/note/メディア付き投稿はattachmentにDocumentとして画像が存在する.sql") - @WithMockHttpSignature - fun メディア付き投稿はattachmentにDocumentとして画像が存在する() { - mockMvc - .get("/users/test-user10/posts/1242") { - accept(MediaType("application", "activity+json")) - } - .asyncDispatch() - .andDo { print() } - .andExpect { status { isOk() } } - .andExpect { content { contentType("application/activity+json") } } - .andExpect { jsonPath("\$.type") { value("Note") } } - .andExpect { jsonPath("\$.attachment") { isArray() } } - .andExpect { jsonPath("\$.attachment[0].type") { value("Document") } } - .andExpect { jsonPath("\$.attachment[0].url") { value("https://example.com/media/test-media.png") } } - .andExpect { jsonPath("\$.attachment[1].type") { value("Document") } } - .andExpect { jsonPath("\$.attachment[1].url") { value("https://example.com/media/test-media2.png") } } - } - - @Test - fun signatureヘッダーがあるのにhostヘッダーがないと401() { - mockMvc - .get("/users/test-user10/posts/9999") { - accept(MediaType("application", "activity+json")) - header("Signature", "a") - header("Date", ZonedDateTime.now().format(dateTimeFormatter)) - - } - .andExpect { status { isUnauthorized() } } - } - - @Test - fun signatureヘッダーがあるのにdateヘッダーがないと401() { - mockMvc - .get("/users/test-user10/posts/9999") { - accept(MediaType("application", "activity+json")) - header("Signature", "a") - header("Host", "example.com") - } - .andExpect { status { isUnauthorized() } } - } - - companion object { - @JvmStatic - @AfterAll - fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { - flyway.clean() - flyway.migrate() - runBlocking { - owlProducer.stop() - } - } - } -} diff --git a/hideout-core/src/intTest/kotlin/activitypub/webfinger/WebFingerTest.kt b/hideout-core/src/intTest/kotlin/activitypub/webfinger/WebFingerTest.kt deleted file mode 100644 index e7532b18..00000000 --- a/hideout-core/src/intTest/kotlin/activitypub/webfinger/WebFingerTest.kt +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package activitypub.webfinger - -import dev.usbharu.hideout.SpringApplication -import dev.usbharu.hideout.core.application.shared.Transaction -import dev.usbharu.owl.producer.api.OwlProducer -import kotlinx.coroutines.runBlocking -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.test.context.TestConfiguration -import org.springframework.context.annotation.Bean -import org.springframework.test.context.jdbc.Sql -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.get -import org.springframework.transaction.annotation.Transactional -import util.TestTransaction -import java.net.URL - -@SpringBootTest(classes = [SpringApplication::class]) -@AutoConfigureMockMvc -@Transactional -class WebFingerTest { - @Autowired - private lateinit var mockMvc: MockMvc - - @Test - @Sql("/sql/test-user.sql") - - fun `webfinger 存在するユーザーを取得`() { - mockMvc - .get("/.well-known/webfinger?resource=acct:test-user@example.com") - .andExpect { status { isOk() } } - .andExpect { header { string("Content-Type", "application/json") } } - .andExpect { - jsonPath("\$.subject") { - value("acct:test-user@example.com") - } - } - .andExpect { - jsonPath("\$.links[0].rel") { - value("self") - } - } - .andExpect { - jsonPath("\$.links[0].href") { value("https://example.com/users/test-user") } - } - .andExpect { - jsonPath("\$.links[0].type") { - value("application/activity+json") - } - } - } - - @Test - fun `webfinger 存在しないユーザーに404`() { - mockMvc - .get("/.well-known/webfinger?resource=acct:invalid-user-notfound-afdjashfal@example.com") - .andExpect { status { isNotFound() } } - } - - @Test - fun `webfinger 不正なリクエストは400`() { - mockMvc - .get("/.well-known/webfinger?res=acct:test") - .andExpect { status { isBadRequest() } } - } - - @Test - fun `webfinger acctのパースが出来なくても400`() { - mockMvc - .get("/.well-known/webfinger?resource=acct:@a@b@c@d") - .andExpect { status { isBadRequest() } } - } - - @TestConfiguration - class Configuration { - @Bean - fun url(): URL { - return URL("https://example.com") - } - - @Bean - fun testTransaction(): Transaction = TestTransaction - } - - companion object { - @JvmStatic - @AfterAll - fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { - flyway.clean() - flyway.migrate() - runBlocking { - owlProducer.stop() - } - } - } -} diff --git a/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiPaginationTest.kt b/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiPaginationTest.kt deleted file mode 100644 index baf0a42a..00000000 --- a/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiPaginationTest.kt +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@file:Suppress("SpringJavaInjectionPointsAutowiringInspection") - -package mastodon.account - -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import dev.usbharu.hideout.SpringApplication -import dev.usbharu.hideout.domain.mastodon.model.generated.Status -import dev.usbharu.owl.producer.api.OwlProducer -import kotlinx.coroutines.runBlocking -import org.assertj.core.api.Assertions.assertThat -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.security.core.authority.SimpleGrantedAuthority -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers -import org.springframework.test.context.jdbc.Sql -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.get -import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.context.WebApplicationContext - -@Suppress("NonAsciiCharacters") -@SpringBootTest(classes = [SpringApplication::class]) -@AutoConfigureMockMvc -@Transactional -@Sql("/sql/test-user.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -@Sql("/sql/test-user2.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -@Sql("/sql/accounts/test-accounts-statuses.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -class AccountApiPaginationTest { - @Suppress("SpringJavaInjectionPointsAutowiringInspection") - @Autowired - private lateinit var context: WebApplicationContext - - private lateinit var mockMvc: MockMvc - - @Test - fun `apiV1AccountsIdStatusesGet 投稿を取得できる`() { - val content = mockMvc - .get("/api/v1/accounts/1/statuses"){ - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - .andExpect { header { string("Link","; rel=\"next\", ; rel=\"prev\"") } } - .andReturn() - .response - .contentAsString - - val value = jacksonObjectMapper().readValue(content, object : TypeReference>() {}) - - assertThat(value.first().id).isEqualTo("100") - assertThat(value.last().id).isEqualTo("81") - assertThat(value).size().isEqualTo(20) - } - - @Test - fun `apiV1AccountsIdStatusesGet 結果が0件のときはLinkヘッダーがない`() { - val content = mockMvc - .get("/api/v1/accounts/1/statuses?min_id=100"){ - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - .andExpect { header { doesNotExist("Link") } } - .andReturn() - .response - .contentAsString - - val value = jacksonObjectMapper().readValue(content, object : TypeReference>() {}) - - - assertThat(value).isEmpty() - } - - @Test - fun `apiV1AccountsIdStatusesGet maxIdを指定して取得`() { - val content = mockMvc - .get("/api/v1/accounts/1/statuses?max_id=100"){ - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - .andExpect { header { string("Link","; rel=\"next\", ; rel=\"prev\"") } } - .andReturn() - .response - .contentAsString - - val value = jacksonObjectMapper().readValue(content, object : TypeReference>() {}) - - assertThat(value.first().id).isEqualTo("99") - assertThat(value.last().id).isEqualTo("80") - assertThat(value).size().isEqualTo(20) - } - - @Test - fun `apiV1AccountsIdStatusesGet minIdを指定して取得`() { - val content = mockMvc - .get("/api/v1/accounts/1/statuses?min_id=1"){ - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - .andExpect { header { string("Link","; rel=\"next\", ; rel=\"prev\"") } } - .andReturn() - .response - .contentAsString - - val value = jacksonObjectMapper().readValue(content, object : TypeReference>() {}) - - assertThat(value.first().id).isEqualTo("21") - assertThat(value.last().id).isEqualTo("2") - assertThat(value).size().isEqualTo(20) - } - - @BeforeEach - fun setUp() { - mockMvc = MockMvcBuilders.webAppContextSetup(context) - .apply(SecurityMockMvcConfigurers.springSecurity()) - .build() - } - - companion object { - @JvmStatic - @AfterAll - fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { - flyway.clean() - flyway.migrate() - runBlocking { - owlProducer.stop() - } - } - - } -} \ No newline at end of file diff --git a/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiTest.kt b/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiTest.kt deleted file mode 100644 index d48c72d8..00000000 --- a/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiTest.kt +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mastodon.account - -import dev.usbharu.hideout.SpringApplication -import dev.usbharu.owl.producer.api.OwlProducer -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.test.runTest -import org.assertj.core.api.Assertions.assertThat -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.http.MediaType -import org.springframework.security.core.authority.SimpleGrantedAuthority -import org.springframework.security.test.context.support.WithAnonymousUser -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.jwt -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity -import org.springframework.test.context.jdbc.Sql -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.get -import org.springframework.test.web.servlet.post -import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.context.WebApplicationContext - -@SpringBootTest(classes = [SpringApplication::class]) -@AutoConfigureMockMvc -@Transactional -@Sql("/sql/test-user.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -@Sql("/sql/test-user2.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -class AccountApiTest { - - @Autowired - private lateinit var followerQueryServiceImpl: FollowerQueryServiceImpl - - @Autowired - private lateinit var actorRepository: ActorRepository - - - @Autowired - private lateinit var context: WebApplicationContext - - private lateinit var mockMvc: MockMvc - - @BeforeEach - fun setUp() { - mockMvc = MockMvcBuilders.webAppContextSetup(context) - .apply(springSecurity()) - .build() - } - - @Test - fun `apiV1AccountsVerifyCredentialsGetにreadでアクセスできる`() { - mockMvc - .get("/api/v1/accounts/verify_credentials") { - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read"))) - } - .asyncDispatch() - .andDo { print() } - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1AccountsVerifyCredentialsGetにread_accountsでアクセスできる`() { - mockMvc - .get("/api/v1/accounts/verify_credentials") { - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:accounts"))) - } - .asyncDispatch() - .andDo { print() } - .andExpect { status { isOk() } } - } - - @Test - @WithAnonymousUser - fun apiV1AccountsVerifyCredentialsGetに匿名でアクセスすると401() { - mockMvc - .get("/api/v1/accounts/verify_credentials") - .andExpect { status { isUnauthorized() } } - } - - @Test - @WithAnonymousUser - fun apiV1AccountsPostに匿名でPOSTしたらアカウントを作成できる() = runTest { - mockMvc - .post("/api/v1/accounts") { - contentType = MediaType.APPLICATION_FORM_URLENCODED - param("username", "api-test-user-1") - param("password", "very-secure-password") - param("email", "test@example.com") - param("agreement", "true") - param("locale", "") - with(jwt()) - with(csrf()) - } - .asyncDispatch() - .andExpect { status { isFound() } } - - actorRepository.findByNameAndDomain("api-test-user-1", "example.com") - } - - @Test - @WithAnonymousUser - fun apiV1AccountsPostで必須パラメーター以外を省略しても作成できる() = runTest { - mockMvc - .post("/api/v1/accounts") { - contentType = MediaType.APPLICATION_FORM_URLENCODED - param("username", "api-test-user-2") - param("password", "very-secure-password") - with(jwt()) - with(csrf()) - } - .asyncDispatch() - .andExpect { status { isFound() } } - - actorRepository.findByNameAndDomain("api-test-user-2", "example.com") - } - - @Test - @WithAnonymousUser - fun apiV1AccountsPostでusernameパラメーターを省略したら400() = runTest { - mockMvc - .post("/api/v1/accounts") { - contentType = MediaType.APPLICATION_FORM_URLENCODED - param("password", "api-test-user-3") - with(csrf()) - with(jwt()) - } - .andDo { print() } - .andExpect { status { isUnprocessableEntity() } } - } - - @Test - @WithAnonymousUser - fun apiV1AccountsPostでpasswordパラメーターを省略したら400() = runTest { - mockMvc - .post("/api/v1/accounts") { - contentType = MediaType.APPLICATION_FORM_URLENCODED - param("username", "api-test-user-4") - with(csrf()) - with(jwt()) - } - .andExpect { status { isUnprocessableEntity() } } - } - - @Test - @Disabled("JSONでも作れるようにするため") - @WithAnonymousUser - fun apiV1AccountsPostでJSONで作ろうとしても400() { - mockMvc - .post("/api/v1/accounts") { - contentType = MediaType.APPLICATION_JSON - content = """{"username":"api-test-user-5","password":"very-very-secure-password"}""" - with(csrf()) - } - .andExpect { status { isUnsupportedMediaType() } } - } - - @Test - @WithAnonymousUser - fun apiV1AccountsPostにCSRFトークンは必要() { - mockMvc - .post("/api/v1/accounts") { - contentType = MediaType.APPLICATION_FORM_URLENCODED - param("username", "api-test-user-2") - param("password", "very-secure-password") - } - .andExpect { status { isForbidden() } } - } - - @Test - @WithAnonymousUser - fun `apiV1AccountsIdGet 匿名でアカウント情報を取得できる`() { - mockMvc - .get("/api/v1/accounts/1") - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1AccountsIdFollowPost write_follows権限でPOSTでフォローできる`() { - mockMvc - .post("/api/v1/accounts/2/follow") { - contentType = MediaType.APPLICATION_JSON - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:follows"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1AccountsIdFollowPost write権限でPOSTでフォローできる`() { - mockMvc - .post("/api/v1/accounts/2/follow") { - contentType = MediaType.APPLICATION_JSON - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1AccountsIdFollowPost read権限でだと403`() { - mockMvc - .post("/api/v1/accounts/2/follow") { - contentType = MediaType.APPLICATION_JSON - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read"))) - } - .andExpect { status { isForbidden() } } - } - - @Test - @WithAnonymousUser - fun `apiV1AAccountsIdFollowPost 匿名だと401`() { - mockMvc - .post("/api/v1/accounts/2/follow") { - contentType = MediaType.APPLICATION_JSON - with(csrf()) - } - .andExpect { status { isUnauthorized() } } - } - - @Test - @WithAnonymousUser - fun `apiV1AAccountsIdFollowPost 匿名の場合通常csrfトークンは持ってないので403`() { - mockMvc - .post("/api/v1/accounts/2/follow") { - contentType = MediaType.APPLICATION_JSON - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV1AccountsRelationshipsGet 匿名だと401`() { - mockMvc - .get("/api/v1/accounts/relationships") - .andExpect { status { isUnauthorized() } } - } - - @Test - fun `apiV1AccountsRelationshipsGet read_follows権限を持っていたら取得できる`() { - mockMvc - .get("/api/v1/accounts/relationships") { - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:follows"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1AccountsRelationshipsGet read権限を持っていたら取得できる`() { - mockMvc - .get("/api/v1/accounts/relationships") { - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1AccountsRelationshipsGet write権限だと403`() { - mockMvc - .get("/api/v1/accounts/relationships") { - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write"))) - } - .andExpect { status { isForbidden() } } - } - - @Test - @Sql("/sql/accounts/apiV1AccountsIdFollowPost フォローできる.sql") - fun `apiV1AccountsIdFollowPost フォローできる`() = runTest { - mockMvc - .post("/api/v1/accounts/3733363/follow") { - contentType = MediaType.APPLICATION_JSON - with(jwt().jwt { it.claim("uid", "37335363") }.authorities(SimpleGrantedAuthority("SCOPE_write"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - - val alreadyFollow = followerQueryServiceImpl.alreadyFollow(3733363, 37335363) - - assertThat(alreadyFollow).isTrue() - } - - @Test - fun `apiV1AccountsIdMutePost write権限でミュートできる`() { - mockMvc - .post("/api/v1/accounts/2/mute") { - contentType = MediaType.APPLICATION_JSON - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1AccountsIdMutePost write_mutes権限でミュートできる`() { - mockMvc - .post("/api/v1/accounts/2/mute") { - contentType = MediaType.APPLICATION_JSON - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:mutes"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1AccountsIdMutePost read権限だと403`() = runTest { - mockMvc - .post("/api/v1/accounts/2/mute") { - contentType = MediaType.APPLICATION_JSON - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read"))) - } - .andExpect { status { isForbidden() } } - } - - @Test - @WithAnonymousUser - fun `apiV1AccountsIdMutePost 匿名だと401`() = runTest { - mockMvc - .post("/api/v1/accounts/2/mute") { - contentType = MediaType.APPLICATION_JSON - with(csrf()) - } - .andExpect { status { isUnauthorized() } } - } - - @Test - @WithAnonymousUser - fun `apiV1AccountsIdMutePost csrfトークンがないと403`() = runTest { - mockMvc - .post("/api/v1/accounts/2/mute") { - contentType = MediaType.APPLICATION_JSON - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV1AccountsIdUnmutePost write権限でアンミュートできる`() { - mockMvc - .post("/api/v1/accounts/2/unmute") { - contentType = MediaType.APPLICATION_JSON - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1AccountsIdUnmutePost write_mutes権限でアンミュートできる`() { - mockMvc - .post("/api/v1/accounts/2/unmute") { - contentType = MediaType.APPLICATION_JSON - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:mutes"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1AccountsIdUnmutePost read権限だと403`() = runTest { - mockMvc - .post("/api/v1/accounts/2/unmute") { - contentType = MediaType.APPLICATION_JSON - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read"))) - } - .andExpect { status { isForbidden() } } - } - - @Test - @WithAnonymousUser - fun `apiV1AccountsIdUnmutePost 匿名だと401`() = runTest { - mockMvc - .post("/api/v1/accounts/2/unmute") { - contentType = MediaType.APPLICATION_JSON - with(csrf()) - } - .andExpect { status { isUnauthorized() } } - } - - @Test - @WithAnonymousUser - fun `apiV1AccountsIdUnmutePost csrfトークンがないと403`() = runTest { - mockMvc - .post("/api/v1/accounts/2/unmute") { - contentType = MediaType.APPLICATION_JSON - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV1MutesGet read権限でミュートしているアカウント一覧を取得できる`() { - mockMvc - .get("/api/v1/mutes") { - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1MutesGet read_mutes権限でミュートしているアカウント一覧を取得できる`() { - mockMvc - .get("/api/v1/mutes") { - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:mutes"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1MutesGet write権限だと403`() { - mockMvc - .get("/api/v1/mutes") { - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write"))) - } - .andExpect { status { isForbidden() } } - } - - @Test - @WithAnonymousUser - fun `apiV1MutesGet 匿名だと401`() { - mockMvc - .get("/api/v1/mutes") - .andExpect { status { isUnauthorized() } } - } - - @Test - fun `apiV1AccountsIdStatusesGet read権限で取得できる`() { - mockMvc - .get("/api/v1/accounts/1/statuses") - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - @WithAnonymousUser - fun `apiV1AccountsIdStatusesGet 匿名でもpublic投稿を取得できる`() { - mockMvc - .get("/api/v1/accounts/1/statuses") - .asyncDispatch() - .andExpect { status { isOk() } } - } - - companion object { - @JvmStatic - @AfterAll - fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { - flyway.clean() - flyway.migrate() - runBlocking { - owlProducer.stop() - } - } - } -} diff --git a/hideout-core/src/intTest/kotlin/mastodon/apps/AppTest.kt b/hideout-core/src/intTest/kotlin/mastodon/apps/AppTest.kt deleted file mode 100644 index 8b8ff123..00000000 --- a/hideout-core/src/intTest/kotlin/mastodon/apps/AppTest.kt +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mastodon.apps - -import dev.usbharu.hideout.SpringApplication -import dev.usbharu.owl.producer.api.OwlProducer -import kotlinx.coroutines.runBlocking -import org.assertj.core.api.Assertions.assertThat -import org.flywaydb.core.Flyway -import org.jetbrains.exposed.sql.selectAll -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.http.MediaType -import org.springframework.security.oauth2.server.authorization.client.RegisteredClient -import org.springframework.security.test.context.support.WithAnonymousUser -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.post -import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.context.WebApplicationContext - -@SpringBootTest(classes = [SpringApplication::class]) -@AutoConfigureMockMvc -@Transactional -class AppTest { - - @Autowired - private lateinit var context: WebApplicationContext - - private lateinit var mockMvc: MockMvc - - - @BeforeEach - fun setUp() { - mockMvc = MockMvcBuilders.webAppContextSetup(context) - .apply(SecurityMockMvcConfigurers.springSecurity()) - .build() - } - - @Test - @WithAnonymousUser - fun apiV1AppsPostにformで匿名でappを作成できる() { - mockMvc - .post("/api/v1/apps") { - contentType = MediaType.APPLICATION_FORM_URLENCODED - param("client_name", "test-client") - param("redirect_uris", "https://example.com") - param("scopes", "write read") - param("website", "https://example.com") - } - .asyncDispatch() - .andExpect { status { isOk() } } - - - val app = RegisteredClient - .selectAll().where { RegisteredClient.clientName eq "test-client" } - .single() - - assertThat(app[RegisteredClient.clientName]).isEqualTo("test-client") - assertThat(app[RegisteredClient.redirectUris]).isEqualTo("https://example.com") - assertThat(app[RegisteredClient.scopes]).isEqualTo("read,write") - } - - @Test - @WithAnonymousUser - fun apiV1AppsPostにjsonで匿名でappを作成できる() { - mockMvc - .post("/api/v1/apps") { - contentType = MediaType.APPLICATION_JSON - content = """{ - "client_name": "test-client-2", - "redirect_uris": "https://example.com", - "scopes": "write read", - "website": "https;//example.com" -}""" - } - .asyncDispatch() - .andExpect { status { isOk() } } - - val app = RegisteredClient - .selectAll().where { RegisteredClient.clientName eq "test-client-2" } - .single() - - assertThat(app[RegisteredClient.clientName]).isEqualTo("test-client-2") - assertThat(app[RegisteredClient.redirectUris]).isEqualTo("https://example.com") - assertThat(app[RegisteredClient.scopes]).isEqualTo("read,write") - } - - companion object { - @JvmStatic - @AfterAll - fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { - flyway.clean() - flyway.migrate() - runBlocking { - owlProducer.stop() - } - } - } -} diff --git a/hideout-core/src/intTest/kotlin/mastodon/filter/FilterTest.kt b/hideout-core/src/intTest/kotlin/mastodon/filter/FilterTest.kt deleted file mode 100644 index 2732663e..00000000 --- a/hideout-core/src/intTest/kotlin/mastodon/filter/FilterTest.kt +++ /dev/null @@ -1,714 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mastodon.filter - -import dev.usbharu.hideout.SpringApplication -import dev.usbharu.hideout.domain.mastodon.model.generated.FilterKeywordsPostRequest -import dev.usbharu.hideout.domain.mastodon.model.generated.FilterPostRequest -import dev.usbharu.hideout.domain.mastodon.model.generated.FilterPostRequestKeyword -import dev.usbharu.hideout.domain.mastodon.model.generated.V1FilterPostRequest -import dev.usbharu.owl.producer.api.OwlProducer -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.test.runTest -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.http.MediaType -import org.springframework.security.core.authority.SimpleGrantedAuthority -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.jwt -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers -import org.springframework.test.context.jdbc.Sql -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.delete -import org.springframework.test.web.servlet.get -import org.springframework.test.web.servlet.post -import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.context.WebApplicationContext - -@SpringBootTest(classes = [SpringApplication::class]) -@AutoConfigureMockMvc -@Transactional -@Sql("/sql/test-user.sql", "/sql/filter/test-filter.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -class FilterTest { - @Autowired - private lateinit var context: WebApplicationContext - - private lateinit var mockMvc: MockMvc - - @BeforeEach - fun setUp() { - mockMvc = MockMvcBuilders.webAppContextSetup(context) - .apply(SecurityMockMvcConfigurers.springSecurity()) - .build() - } - - @Test - fun `apiV2FiltersPost write権限で追加できる`() { - mockMvc - .post("/api/v2/filters") { - contentType = MediaType.APPLICATION_JSON - content = ActivityPubConfig().objectMapper().writeValueAsString( - FilterPostRequest( - title = "mute test", - context = listOf(FilterPostRequest.Context.home, FilterPostRequest.Context.public), - filterAction = FilterPostRequest.FilterAction.warn, - expiresIn = null, - keywordsAttributes = listOf( - FilterPostRequestKeyword( - keyword = "hoge", - wholeWord = false, - regex = true - ) - ) - ) - ) - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - .andExpect { - content { - jsonPath("$.keywords[0].keyword") { - value("hoge") - } - } - } - } - - @Test - fun `apiV2FiltersPost write_filters権限で追加できる`() { - mockMvc - .post("/api/v2/filters") { - contentType = MediaType.APPLICATION_JSON - content = ActivityPubConfig().objectMapper().writeValueAsString( - FilterPostRequest( - title = "mute test", - context = listOf(FilterPostRequest.Context.home, FilterPostRequest.Context.public), - filterAction = FilterPostRequest.FilterAction.warn, - expiresIn = null, - keywordsAttributes = listOf( - FilterPostRequestKeyword( - keyword = "fuga", - wholeWord = true, - regex = false - ) - ) - ) - ) - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - .andExpect { - content { - jsonPath("$.keywords[0].keyword") { - value("fuga") - } - } - } - } - - @Test - fun `apiV2FiltersPost read権限で401`() { - mockMvc - .post("/api/v2/filters") { - contentType = MediaType.APPLICATION_JSON - content = ActivityPubConfig().objectMapper().writeValueAsString( - FilterPostRequest( - title = "mute test", - context = listOf(FilterPostRequest.Context.home, FilterPostRequest.Context.public), - filterAction = FilterPostRequest.FilterAction.warn, - expiresIn = null, - keywordsAttributes = listOf( - FilterPostRequestKeyword( - keyword = "fuga", - wholeWord = true, - regex = false - ) - ) - ) - ) - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV2FiltersGet read権限で取得できる`() { - mockMvc - .get("/api/v2/filters") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersGet read_filters権限で取得できる`() { - mockMvc - .get("/api/v2/filters") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersGet write権限で401`() { - mockMvc - .get("/api/v2/filters") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV2FiltersIdGet read権限で取得できる`() { - mockMvc - .get("/api/v2/filters/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - - @Test - fun `apiV2FiltersIdGet read_filters権限で取得できる`() { - mockMvc - .get("/api/v2/filters/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersIdGet write権限で401`() { - mockMvc - .get("/api/v2/filters/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV2FiltersFilterIdKeywordsGet read権限で取得できる`() { - mockMvc - .get("/api/v2/filters/1/keywords") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersFilterIdKeywordsGet read_filters権限で取得できる`() { - mockMvc - .get("/api/v2/filters/1/keywords") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersFilterIdKeywordsGet writeで403`() { - mockMvc - .get("/api/v2/filters/1/keywords") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV2FiltersFilterIdKeywordsPost writeで追加できる`() { - mockMvc - .post("/api/v2/filters/1/keywords") { - contentType = MediaType.APPLICATION_JSON - content = ActivityPubConfig().objectMapper().writeValueAsString( - FilterKeywordsPostRequest( - "hage", false, false - ) - ) - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersFilterIdKeywordsPost write_filtersで追加できる`() { - mockMvc - .post("/api/v2/filters/1/keywords") { - contentType = MediaType.APPLICATION_JSON - content = ActivityPubConfig().objectMapper().writeValueAsString( - FilterKeywordsPostRequest( - "hage", false, false - ) - ) - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersFilterIdKeywordsPost readで403`() { - mockMvc - .post("/api/v2/filters/1/keywords") { - contentType = MediaType.APPLICATION_JSON - content = ActivityPubConfig().objectMapper().writeValueAsString( - FilterKeywordsPostRequest( - "hage", false, false - ) - ) - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV2FiltersKeywordsIdGet readで取得できる`() { - mockMvc - .get("/api/v2/filters/keywords/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersKeywordsIdGet read_filtersで取得できる`() { - mockMvc - .get("/api/v2/filters/keywords/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersKeywordsIdGet writeだと403`() { - mockMvc - .get("/api/v2/filters/keywords/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV2FiltersKeyowrdsIdDelete writeで削除できる`() = runTest { - mockMvc - .delete("/api/v2/filters/keywords/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersKeyowrdsIdDelete write_filtersで削除できる`() = runTest { - mockMvc - .delete("/api/v2/filters/keywords/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersKeyowrdsIdDelete readで403`() = runTest { - mockMvc - .delete("/api/v2/filters/keywords/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV2FiltersFilterIdStatuses readで取得できる`() { - mockMvc - .get("/api/v2/filters/1/statuses") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersFilterIdStatuses read_filtersで取得できる`() { - mockMvc - .get("/api/v2/filters/1/statuses") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersFilterIdStatuses writeで403`() { - mockMvc - .get("/api/v2/filters/1/statuses") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV2FiltersStatusesIdGet readで取得できる`() { - mockMvc - .get("/api/v2/filters/statuses/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersStatusesIdGet read_filtersで取得できる`() { - mockMvc - .get("/api/v2/filters/statuses/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersStatusesIdGet writeで403`() { - mockMvc - .get("/api/v2/filters/statuses/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV2FiltersStatusesIdDelete writeで削除できる`() { - mockMvc - .delete("/api/v2/filters/statuses/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersStatusesIdDelete write_filtersで削除できる`() { - mockMvc - .delete("/api/v2/filters/statuses/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV2FiltersStatusesIdDelete readで403`() { - mockMvc - .delete("/api/v2/filters/statuses/1") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV1FiltersGet readで取得できる`() { - mockMvc - .get("/api/v1/filters") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1FiltersGet read_filtersで取得できる`() { - mockMvc - .get("/api/v1/filters") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1FiltersGet writeで403`() { - mockMvc - .get("/api/v1/filters") { - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV1FiltersPost writeで新規作成`() { - mockMvc - .post("/api/v1/filters") { - contentType = MediaType.APPLICATION_JSON - content = ActivityPubConfig().objectMapper().writeValueAsString( - V1FilterPostRequest( - phrase = "hoge", - context = listOf(V1FilterPostRequest.Context.home), - irreversible = false, - wholeWord = false, - expiresIn = null - ) - ) - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1FiltersPost write_filtersで新規作成`() { - mockMvc - .post("/api/v1/filters") { - contentType = MediaType.APPLICATION_JSON - content = ActivityPubConfig().objectMapper().writeValueAsString( - V1FilterPostRequest( - phrase = "hoge", - context = listOf(V1FilterPostRequest.Context.home), - irreversible = false, - wholeWord = false, - expiresIn = null - ) - ) - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1FiltersPost readで403`() { - mockMvc - .post("/api/v1/filters") { - contentType = MediaType.APPLICATION_JSON - content = ActivityPubConfig().objectMapper().writeValueAsString( - V1FilterPostRequest( - phrase = "hoge", - context = listOf(V1FilterPostRequest.Context.home), - irreversible = false, - wholeWord = false, - expiresIn = null - ) - ) - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV1FiltersIdGet readで取得できる`() { - mockMvc - .get("/api/v1/filters/1") { - with( - jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1FiltersIdGet read_filtersで取得できる`() { - mockMvc - .get("/api/v1/filters/1") { - with( - jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1FiltersIdGet writeで403`() { - mockMvc - .get("/api/v1/filters/1") { - with( - jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - fun `apiV1FiltersIdDelete writeで削除できる`() { - mockMvc - .delete("/api/v1/filters/1") { - with( - jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1FiltersIdDelete write_filtersで削除できる`() { - mockMvc - .delete("/api/v1/filters/1") { - with( - jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:filters")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1FiltersIdDelete readで403`() { - mockMvc - .delete("/api/v1/filters/1") { - with( - jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - companion object { - @JvmStatic - @AfterAll - fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { - flyway.clean() - flyway.migrate() - runBlocking { - owlProducer.stop() - } - } - } -} \ No newline at end of file diff --git a/hideout-core/src/intTest/kotlin/mastodon/media/MediaTest.kt b/hideout-core/src/intTest/kotlin/mastodon/media/MediaTest.kt deleted file mode 100644 index 77f23281..00000000 --- a/hideout-core/src/intTest/kotlin/mastodon/media/MediaTest.kt +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mastodon.media - -import dev.usbharu.hideout.SpringApplication -import dev.usbharu.hideout.core.service.media.MediaDataStore -import dev.usbharu.hideout.core.service.media.MediaSaveRequest -import dev.usbharu.hideout.core.service.media.SuccessSavedMedia -import dev.usbharu.owl.producer.api.OwlProducer -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.test.runTest -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.mockito.kotlin.any -import org.mockito.kotlin.doReturn -import org.mockito.kotlin.whenever -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.test.mock.mockito.MockBean -import org.springframework.mock.web.MockMultipartFile -import org.springframework.security.core.authority.SimpleGrantedAuthority -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.jwt -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers -import org.springframework.test.context.jdbc.Sql -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.multipart -import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.context.WebApplicationContext - -@SpringBootTest(classes = [SpringApplication::class]) -@AutoConfigureMockMvc -@Transactional -@Sql("/sql/test-user.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -class MediaTest { - - @Autowired - private lateinit var context: WebApplicationContext - - private lateinit var mockMvc: MockMvc - - - @MockBean - private lateinit var mediaDataStore: MediaDataStore - - @BeforeEach - fun setUp() { - mockMvc = MockMvcBuilders.webAppContextSetup(context) - .apply(SecurityMockMvcConfigurers.springSecurity()) - .build() - } - - @Test - fun メディアをアップロードできる() = runTest { - whenever(mediaDataStore.save(any())).doReturn(SuccessSavedMedia("", "a", "a")) - - mockMvc - .multipart("/api/v1/media") { - - file( - MockMultipartFile( - "file", - "400x400.png", - "image/png", - String.javaClass.classLoader.getResourceAsStream("media/400x400.png") - ) - ) - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun write_mediaスコープでメディアをアップロードできる() = runTest { - whenever(mediaDataStore.save(any())).doReturn(SuccessSavedMedia("", "b", "b")) - - mockMvc - .multipart("/api/v1/media") { - - file( - MockMultipartFile( - "file", - "400x400.png", - "image/png", - String.javaClass.classLoader.getResourceAsStream("media/400x400.png") - ) - ) - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:media"))) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun 権限がないと403() = runTest { - whenever(mediaDataStore.save(any())).doReturn(SuccessSavedMedia("", "", "")) - - mockMvc - .multipart("/api/v1/media") { - - file( - MockMultipartFile( - "file", - "400x400.png", - "image/png", - String.javaClass.classLoader.getResourceAsStream("media/400x400.png") - ) - ) - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read"))) - } - .andExpect { status { isForbidden() } } - } - - companion object { - @JvmStatic - @AfterAll - fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { - flyway.clean() - flyway.migrate() - runBlocking { - owlProducer.stop() - } - } - } - -} diff --git a/hideout-core/src/intTest/kotlin/mastodon/notifications/ExposedNotificationsApiPaginationTest.kt b/hideout-core/src/intTest/kotlin/mastodon/notifications/ExposedNotificationsApiPaginationTest.kt deleted file mode 100644 index 7405caf6..00000000 --- a/hideout-core/src/intTest/kotlin/mastodon/notifications/ExposedNotificationsApiPaginationTest.kt +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mastodon.notifications - -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import dev.usbharu.hideout.SpringApplication -import dev.usbharu.hideout.domain.mastodon.model.generated.Notification -import dev.usbharu.owl.producer.api.OwlProducer -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.test.runTest -import org.assertj.core.api.Assertions.assertThat -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.security.core.authority.SimpleGrantedAuthority -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers -import org.springframework.test.context.jdbc.Sql -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.get -import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.context.WebApplicationContext - -@SpringBootTest(classes = [SpringApplication::class], properties = ["hideout.use-mongodb=false"]) -@AutoConfigureMockMvc -@Transactional -@Sql("/sql/test-user.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -@Sql("/sql/test-user2.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -@Sql("/sql/notification/test-notifications.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -@Sql("/sql/notification/test-mastodon_notifications.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -class ExposedNotificationsApiPaginationTest { - @Autowired - private lateinit var context: WebApplicationContext - - private lateinit var mockMvc: MockMvc - - @Test - fun `通知を取得できる`() = runTest { - val content = mockMvc - .get("/api/v1/notifications") { - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { - header { - string( - "Link", - "; rel=\"next\", ; rel=\"prev\"" - ) - } - } - .andReturn() - .response - .contentAsString - - val value = jacksonObjectMapper().readValue(content, object : TypeReference>() {}) - - assertThat(value.first().id).isEqualTo("65") - assertThat(value.last().id).isEqualTo("26") - } - - @Test - fun maxIdを指定して通知を取得できる() = runTest { - val content = mockMvc - .get("/api/v1/notifications?max_id=26") { - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { - header { - string( - "Link", - "; rel=\"next\", ; rel=\"prev\"" - ) - } - } - .andReturn() - .response - .contentAsString - - val value = jacksonObjectMapper().readValue(content, object : TypeReference>() {}) - - assertThat(value.first().id).isEqualTo("25") - assertThat(value.last().id).isEqualTo("1") - - } - - @Test - fun minIdを指定して通知を取得できる() = runTest { - val content = mockMvc - .get("/api/v1/notifications?min_id=25") { - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { - header { - string( - "Link", - "; rel=\"next\", ; rel=\"prev\"" - ) - } - } - .andReturn() - .response - .contentAsString - - val value = jacksonObjectMapper().readValue(content, object : TypeReference>() {}) - - assertThat(value.first().id).isEqualTo("65") - assertThat(value.last().id).isEqualTo("26") - } - - @Test - fun 結果が0件のときはページネーションのヘッダーがない() = runTest { - val content = mockMvc - .get("/api/v1/notifications?max_id=1") { - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { - header { - doesNotExist("Link") - } - } - .andReturn() - .response - .contentAsString - - val value = jacksonObjectMapper().readValue(content, object : TypeReference>() {}) - - assertThat(value).size().isZero() - } - - @BeforeEach - fun setUp() { - mockMvc = MockMvcBuilders.webAppContextSetup(context) - .apply(SecurityMockMvcConfigurers.springSecurity()) - .build() - } - - companion object { - @JvmStatic - @AfterAll - fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { - flyway.clean() - flyway.migrate() - runBlocking { - owlProducer.stop() - } - } - } -} \ No newline at end of file diff --git a/hideout-core/src/intTest/kotlin/mastodon/notifications/MongodbNotificationsApiPaginationTest.kt b/hideout-core/src/intTest/kotlin/mastodon/notifications/MongodbNotificationsApiPaginationTest.kt deleted file mode 100644 index 0de15332..00000000 --- a/hideout-core/src/intTest/kotlin/mastodon/notifications/MongodbNotificationsApiPaginationTest.kt +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mastodon.notifications - -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import dev.usbharu.hideout.SpringApplication -import dev.usbharu.hideout.domain.mastodon.model.generated.Notification -import dev.usbharu.hideout.mastodon.domain.model.MastodonNotification -import dev.usbharu.hideout.mastodon.domain.model.NotificationType -import dev.usbharu.hideout.mastodon.infrastructure.mongorepository.MongoMastodonNotificationRepository -import dev.usbharu.owl.producer.api.OwlProducer -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.test.runTest -import org.assertj.core.api.Assertions -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.security.core.authority.SimpleGrantedAuthority -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers -import org.springframework.test.context.jdbc.Sql -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.get -import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.context.WebApplicationContext -import java.time.Instant - -@SpringBootTest(classes = [SpringApplication::class], properties = ["hideout.use-mongodb=true"]) -@AutoConfigureMockMvc -@Transactional -@Sql("/sql/test-user.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -@Sql("/sql/test-user2.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -@Sql("/sql/notification/test-notifications.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -class MongodbNotificationsApiPaginationTest { - @Autowired - private lateinit var context: WebApplicationContext - - private lateinit var mockMvc: MockMvc - - @Test - fun `通知を取得できる`() = runTest { - val content = mockMvc - .get("/api/v1/notifications") { - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andDo { print() } - .andExpect { - header { - string( - "Link", - "; rel=\"next\", ; rel=\"prev\"" - ) - } - } - .andReturn() - .response - .contentAsString - - val value = jacksonObjectMapper().readValue(content, object : TypeReference>() {}) - - Assertions.assertThat(value.first().id).isEqualTo("65") - Assertions.assertThat(value.last().id).isEqualTo("26") - } - - @Test - fun maxIdを指定して通知を取得できる() = runTest { - val content = mockMvc - .get("/api/v1/notifications?max_id=26") { - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { - header { - string( - "Link", - "; rel=\"next\", ; rel=\"prev\"" - ) - } - } - .andReturn() - .response - .contentAsString - - val value = jacksonObjectMapper().readValue(content, object : TypeReference>() {}) - - Assertions.assertThat(value.first().id).isEqualTo("25") - Assertions.assertThat(value.last().id).isEqualTo("1") - - } - - @Test - fun minIdを指定して通知を取得できる() = runTest { - val content = mockMvc - .get("/api/v1/notifications?min_id=25") { - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { - header { - string( - "Link", - "; rel=\"next\", ; rel=\"prev\"" - ) - } - } - .andReturn() - .response - .contentAsString - - val value = jacksonObjectMapper().readValue(content, object : TypeReference>() {}) - - Assertions.assertThat(value.first().id).isEqualTo("65") - Assertions.assertThat(value.last().id).isEqualTo("26") - } - - @Test - fun 結果が0件のときはページネーションのヘッダーがない() = runTest { - val content = mockMvc - .get("/api/v1/notifications?max_id=1") { - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { - header { - doesNotExist("Link") - } - } - .andReturn() - .response - .contentAsString - - val value = jacksonObjectMapper().readValue(content, object : TypeReference>() {}) - - Assertions.assertThat(value).size().isZero() - } - - @BeforeEach - fun setUp() { - mockMvc = MockMvcBuilders.webAppContextSetup(context) - .apply(SecurityMockMvcConfigurers.springSecurity()) - .build() - } - - companion object { - @JvmStatic - @BeforeAll - fun setupMongodb( - @Autowired mongoMastodonNotificationRepository: MongoMastodonNotificationRepository, - ) { - - mongoMastodonNotificationRepository.deleteAll() - - val notifications = (1..65).map { - MastodonNotification( - it.toLong(), - 1, - NotificationType.follow, - Instant.now(), - 2, - null, - null, - null - ) - } - - mongoMastodonNotificationRepository.saveAll(notifications) - } - - @JvmStatic - @AfterAll - fun dropDatabase( - @Autowired flyway: Flyway, - @Autowired mongodbMastodonNotificationRepository: MongoMastodonNotificationRepository, - @Autowired owlProducer: OwlProducer, - ) { - flyway.clean() - flyway.migrate() - runBlocking { - owlProducer.stop() - } - mongodbMastodonNotificationRepository.deleteAll() - } - } -} \ No newline at end of file diff --git a/hideout-core/src/intTest/kotlin/mastodon/status/StatusTest.kt b/hideout-core/src/intTest/kotlin/mastodon/status/StatusTest.kt deleted file mode 100644 index d3028a0d..00000000 --- a/hideout-core/src/intTest/kotlin/mastodon/status/StatusTest.kt +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mastodon.status - -import dev.usbharu.hideout.SpringApplication -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji -import dev.usbharu.hideout.core.domain.model.emoji.UnicodeEmoji -import dev.usbharu.hideout.core.infrastructure.exposedrepository.CustomEmojis -import dev.usbharu.owl.producer.api.OwlProducer -import kotlinx.coroutines.runBlocking -import org.assertj.core.api.Assertions.assertThat -import org.flywaydb.core.Flyway -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.selectAll -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.http.MediaType -import org.springframework.security.core.authority.SimpleGrantedAuthority -import org.springframework.security.test.context.support.WithAnonymousUser -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.jwt -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers -import org.springframework.test.context.jdbc.Sql -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.post -import org.springframework.test.web.servlet.put -import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.context.WebApplicationContext -import java.time.Instant - -@SpringBootTest(classes = [SpringApplication::class]) -@AutoConfigureMockMvc -@Transactional -@Sql("/sql/test-user.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -@Sql("/sql/test-post.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -@Sql("/sql/test-custom-emoji.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -class StatusTest { - - @Autowired - private lateinit var context: WebApplicationContext - - private lateinit var mockMvc: MockMvc - - - @BeforeEach - fun setUp() { - mockMvc = MockMvcBuilders.webAppContextSetup(context) - .apply(SecurityMockMvcConfigurers.springSecurity()) - .build() - } - - @Test - fun 投稿できる() { - mockMvc - .post("/api/v1/statuses") { - contentType = MediaType.APPLICATION_JSON - content = """{"status":"hello"}""" - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun write_statusesスコープで投稿できる() { - mockMvc - .post("/api/v1/statuses") { - contentType = MediaType.APPLICATION_JSON - content = """{"status":"hello"}""" - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:statuses")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun 権限がないと403() { - mockMvc - .post("/api/v1/statuses") { - contentType = MediaType.APPLICATION_JSON - content = """{"status":"hello"}""" - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .andExpect { status { isForbidden() } } - } - - @Test - @WithAnonymousUser - fun 匿名だと401() { - mockMvc - .post("/api/v1/statuses") { - contentType = MediaType.APPLICATION_JSON - content = """{"status":"hello"}""" - with(csrf()) - } - .andExpect { status { isUnauthorized() } } - } - - @Test - @WithAnonymousUser - fun 匿名の場合通常はcsrfが無いので403() { - mockMvc - .post("/api/v1/statuses") { - contentType = MediaType.APPLICATION_JSON - content = """{"status":"hello"}""" - } - .andExpect { status { isForbidden() } } - } - - @Test - fun formでも投稿できる() { - mockMvc - .post("/api/v1/statuses") { - contentType = MediaType.APPLICATION_FORM_URLENCODED - param("status", "hello") - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:statuses")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun in_reply_to_idを指定したら返信として処理される() { - mockMvc - .post("/api/v1/statuses") { - contentType = MediaType.APPLICATION_JSON - //language=JSON - content = """{ - "status": "hello", - "in_reply_to_id": "1" -}""" - with( - jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) - ) - } - .asyncDispatch() - .andDo { print() } - .andExpect { status { isOk() } } - .andExpect { jsonPath("\$.in_reply_to_id") { value("1") } } - } - - @Test - fun ユニコード絵文字をリアクションできる() { - mockMvc - .put("/api/v1/statuses/1/emoji_reactions/😭") { - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write"))) - } - .andDo { print() } - .asyncDispatch() - .andExpect { status { isOk() } } - - val reaction = - Reactions.selectAll().where { Reactions.postId eq 1 and (Reactions.actorId eq 1) }.single().toReaction() - assertThat(reaction.emoji).isEqualTo(UnicodeEmoji("😭")) - assertThat(reaction.postId).isEqualTo(1) - assertThat(reaction.actorId).isEqualTo(1) - } - - @Test - fun 存在しない絵文字はフォールバックされる() { - mockMvc - .put("/api/v1/statuses/1/emoji_reactions/hoge") { - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write"))) - } - .andDo { print() } - .asyncDispatch() - .andExpect { status { isOk() } } - - val reaction = - Reactions.selectAll().where { Reactions.postId eq 1 and (Reactions.actorId eq 1) }.single().toReaction() - assertThat(reaction.emoji).isEqualTo(UnicodeEmoji("❤")) - assertThat(reaction.postId).isEqualTo(1) - assertThat(reaction.actorId).isEqualTo(1) - } - - @Test - fun カスタム絵文字をリアクションできる() { - mockMvc - .put("/api/v1/statuses/1/emoji_reactions/kotlin") { - with(jwt().jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write"))) - } - .andDo { print() } - .asyncDispatch() - .andExpect { status { isOk() } } - - val reaction = - Reactions.leftJoin(CustomEmojis).selectAll().where { Reactions.postId eq 1 and (Reactions.actorId eq 1) } - .single() - .toReaction() - assertThat(reaction.emoji).isEqualTo( - CustomEmoji( - 1, - "kotlin", - "example.com", - null, - "https://example.com/emojis/kotlin", - null, - Instant.ofEpochMilli(1704700290036) - ) - ) - } - - companion object { - @JvmStatic - @AfterAll - fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { - flyway.clean() - flyway.migrate() - runBlocking { - owlProducer.stop() - } - } - } -} diff --git a/hideout-core/src/intTest/kotlin/mastodon/timelines/TimelineApiTest.kt b/hideout-core/src/intTest/kotlin/mastodon/timelines/TimelineApiTest.kt deleted file mode 100644 index 21719e85..00000000 --- a/hideout-core/src/intTest/kotlin/mastodon/timelines/TimelineApiTest.kt +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mastodon.timelines - -import dev.usbharu.hideout.SpringApplication -import dev.usbharu.owl.producer.api.OwlProducer -import kotlinx.coroutines.runBlocking -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.security.core.authority.SimpleGrantedAuthority -import org.springframework.security.test.context.support.WithAnonymousUser -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers -import org.springframework.test.context.jdbc.Sql -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.get -import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.context.WebApplicationContext - -@SpringBootTest(classes = [SpringApplication::class]) -@Transactional -@Sql("/sql/test-user.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) -class TimelineApiTest { - @Autowired - private lateinit var context: WebApplicationContext - - private lateinit var mockMvc: MockMvc - - @BeforeEach - fun beforeEach() { - mockMvc = MockMvcBuilders.webAppContextSetup(context) - .apply(SecurityMockMvcConfigurers.springSecurity()) - .build() - } - - @Test - fun `apiV1TimelinesHomeGetにreadでアクセスできる`() { - mockMvc - .get("/api/v1/timelines/home") { - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1TimelinesHomeGetにread statusesでアクセスできる`() { - mockMvc - .get("/api/v1/timelines/home") { - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:statuses")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - @WithAnonymousUser - fun apiV1TimelineHomeGetに匿名でアクセスすると401() { - mockMvc - .get("/api/v1/timelines/home") - .andExpect { status { isUnauthorized() } } - } - - @Test - fun apiV1TimelinesPublicGetにreadでアクセスできる() { - mockMvc - .get("/api/v1/timelines/public") { - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - fun `apiV1TimelinesPublicGetにread statusesでアクセスできる`() { - mockMvc - .get("/api/v1/timelines/public") { - with( - SecurityMockMvcRequestPostProcessors.jwt() - .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read:statuses")) - ) - } - .asyncDispatch() - .andExpect { status { isOk() } } - } - - @Test - @WithAnonymousUser - fun apiV1TimeinesPublicGetに匿名でアクセスできる() { - mockMvc - .get("/api/v1/timelines/public") - .asyncDispatch() - .andExpect { status { isOk() } } - } - - companion object { - @JvmStatic - @AfterAll - fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { - flyway.clean() - flyway.migrate() - runBlocking { - owlProducer.stop() - } - } - } -} diff --git a/hideout-core/src/intTest/kotlin/util/WithHttpSignature.kt b/hideout-core/src/intTest/kotlin/util/WithHttpSignature.kt deleted file mode 100644 index 64fd643f..00000000 --- a/hideout-core/src/intTest/kotlin/util/WithHttpSignature.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package util - -import org.springframework.core.annotation.AliasFor -import org.springframework.security.test.context.support.TestExecutionEvent -import org.springframework.security.test.context.support.WithSecurityContext -import java.lang.annotation.Inherited - -@Target(AnnotationTarget.FUNCTION, AnnotationTarget.TYPE) -@Retention(AnnotationRetention.RUNTIME) -@Inherited -@MustBeDocumented -@WithSecurityContext(factory = WithHttpSignatureSecurityContextFactory::class) -annotation class WithHttpSignature( - @get:AliasFor( - annotation = WithSecurityContext::class - ) val setupBefore: TestExecutionEvent = TestExecutionEvent.TEST_METHOD, - val keyId: String = "https://example.com/users/test-user#pubkey", - val url: String = "https://example.com/inbox", - val method: String = "GET" -) diff --git a/hideout-core/src/intTest/kotlin/util/WithHttpSignatureSecurityContextFactory.kt b/hideout-core/src/intTest/kotlin/util/WithHttpSignatureSecurityContextFactory.kt deleted file mode 100644 index 7ec4aaa5..00000000 --- a/hideout-core/src/intTest/kotlin/util/WithHttpSignatureSecurityContextFactory.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package util - -import dev.usbharu.hideout.core.application.shared.Transaction -import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.infrastructure.springframework.httpsignature.HttpSignatureUser -import dev.usbharu.httpsignature.common.HttpHeaders -import dev.usbharu.httpsignature.common.HttpMethod -import dev.usbharu.httpsignature.common.HttpRequest -import kotlinx.coroutines.runBlocking -import org.springframework.security.core.context.SecurityContext -import org.springframework.security.core.context.SecurityContextHolder -import org.springframework.security.test.context.support.WithSecurityContextFactory -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken -import java.net.URL - -class WithHttpSignatureSecurityContextFactory( - private val actorRepository: ActorRepository, - private val transaction: Transaction -) : WithSecurityContextFactory { - - private val securityContextStrategy = SecurityContextHolder.getContextHolderStrategy() - - override fun createSecurityContext(annotation: WithHttpSignature): SecurityContext = runBlocking { - val preAuthenticatedAuthenticationToken = PreAuthenticatedAuthenticationToken( - annotation.keyId, HttpRequest( - URL("https://example.com/inbox"), - HttpHeaders(mapOf()), HttpMethod.GET - ) - ) - val httpSignatureUser = transaction.transaction { - val findByKeyId = - actorRepository.findByKeyId(annotation.keyId) ?: throw UserNotFoundException.withKeyId(annotation.keyId) - HttpSignatureUser( - findByKeyId.name, - findByKeyId.domain, - findByKeyId.id, - true, - true, - mutableListOf() - ) - } - preAuthenticatedAuthenticationToken.details = httpSignatureUser - preAuthenticatedAuthenticationToken.isAuthenticated = true - val emptyContext = securityContextStrategy.createEmptyContext() - emptyContext.authentication = preAuthenticatedAuthenticationToken - return@runBlocking emptyContext - } - -} diff --git a/hideout-core/src/intTest/kotlin/util/WithMockHttpSignature.kt b/hideout-core/src/intTest/kotlin/util/WithMockHttpSignature.kt deleted file mode 100644 index 86392316..00000000 --- a/hideout-core/src/intTest/kotlin/util/WithMockHttpSignature.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package util - -import org.springframework.core.annotation.AliasFor -import org.springframework.security.test.context.support.TestExecutionEvent -import org.springframework.security.test.context.support.WithSecurityContext -import java.lang.annotation.Inherited - -@Target(AnnotationTarget.FUNCTION, AnnotationTarget.TYPE) -@Retention(AnnotationRetention.RUNTIME) -@Inherited -@MustBeDocumented -@WithSecurityContext(factory = WithMockHttpSignatureSecurityContextFactory::class) -annotation class WithMockHttpSignature( - @get:AliasFor( - annotation = WithSecurityContext::class - ) val setupBefore: TestExecutionEvent = TestExecutionEvent.TEST_METHOD, - val username: String = "test-user", - val domain: String = "example.com", - val keyId: String = "https://example.com/users/test-user#pubkey", - val id: Long = 1234L, - val url: String = "https://example.com/inbox", - val method: String = "GET" -) diff --git a/hideout-core/src/intTest/kotlin/util/WithMockHttpSignatureSecurityContextFactory.kt b/hideout-core/src/intTest/kotlin/util/WithMockHttpSignatureSecurityContextFactory.kt deleted file mode 100644 index 1114bdcd..00000000 --- a/hideout-core/src/intTest/kotlin/util/WithMockHttpSignatureSecurityContextFactory.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package util - -import dev.usbharu.hideout.core.infrastructure.springframework.httpsignature.HttpSignatureUser -import dev.usbharu.httpsignature.common.HttpHeaders -import dev.usbharu.httpsignature.common.HttpMethod -import dev.usbharu.httpsignature.common.HttpRequest -import org.springframework.security.core.context.SecurityContext -import org.springframework.security.core.context.SecurityContextHolder -import org.springframework.security.test.context.support.WithSecurityContextFactory -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken -import java.net.URL - -class WithMockHttpSignatureSecurityContextFactory : - WithSecurityContextFactory { - - private val securityContextStrategy = SecurityContextHolder.getContextHolderStrategy() - - override fun createSecurityContext(annotation: WithMockHttpSignature): SecurityContext { - val preAuthenticatedAuthenticationToken = PreAuthenticatedAuthenticationToken( - annotation.keyId, HttpRequest( - URL(annotation.url), - HttpHeaders(mapOf()), HttpMethod.valueOf(annotation.method.uppercase()) - ) - ) - val httpSignatureUser = HttpSignatureUser( - annotation.username, - annotation.domain, - annotation.id, - true, - true, - mutableListOf() - ) - preAuthenticatedAuthenticationToken.details = httpSignatureUser - preAuthenticatedAuthenticationToken.isAuthenticated = true - val emptyContext = securityContextStrategy.createEmptyContext() - emptyContext.authentication = preAuthenticatedAuthenticationToken - return emptyContext - } -} diff --git a/hideout-core/src/intTest/resources/application.yml b/hideout-core/src/intTest/resources/application.yml deleted file mode 100644 index 57ab70fa..00000000 --- a/hideout-core/src/intTest/resources/application.yml +++ /dev/null @@ -1,40 +0,0 @@ -hideout: - debug: - trace-query-exception: true - trace-query-call: true - url: "https://example.com" - use-mongodb: true - security: - jwt: - generate: true - key-id: a - private-key: "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC7VJTUt9Us8cKjMzEfYyjiWA4R4/M2bS1GB4t7NXp98C3SC6dVMvDuictGeurT8jNbvJZHtCSuYEvuNMoSfm76oqFvAp8Gy0iz5sxjZmSnXyCdPEovGhLa0VzMaQ8s+CLOyS56YyCFGeJZqgtzJ6GR3eqoYSW9b9UMvkBpZODSctWSNGj3P7jRFDO5VoTwCQAWbFnOjDfH5Ulgp2PKSQnSJP3AJLQNFNe7br1XbrhV//eO+t51mIpGSDCUv3E0DDFcWDTH9cXDTTlRZVEiR2BwpZOOkE/Z0/BVnhZYL71oZV34bKfWjQIt6V/isSMahdsAASACp4ZTGtwiVuNd9tybAgMBAAECggEBAKTmjaS6tkK8BlPXClTQ2vpz/N6uxDeS35mXpqasqskVlaAidgg/sWqpjXDbXr93otIMLlWsM+X0CqMDgSXKejLS2jx4GDjI1ZTXg++0AMJ8sJ74pWzVDOfmCEQ/7wXs3+cbnXhKriO8Z036q92Qc1+N87SI38nkGa0ABH9CN83HmQqt4fB7UdHzuIRe/me2PGhIq5ZBzj6h3BpoPGzEP+x3l9YmK8t/1cN0pqI+dQwYdgfGjackLu/2qH80MCF7IyQaseZUOJyKrCLtSD/Iixv/hzDEUPfOCjFDgTpzf3cwta8+oE4wHCo1iI1/4TlPkwmXx4qSXtmw4aQPz7IDQvECgYEA8KNThCO2gsC2I9PQDM/8Cw0O983WCDY+oi+7JPiNAJwv5DYBqEZB1QYdj06YD16XlC/HAZMsMku1na2TN0driwenQQWzoev3g2S7gRDoS/FCJSI3jJ+kjgtaA7Qmzlgk1TxODN+G1H91HW7t0l7VnL27IWyYo2qRRK3jzxqUiPUCgYEAx0oQs2reBQGMVZnApD1jeq7n4MvNLcPvt8b/eU9iUv6Y4Mj0Suo/AU8lYZXm8ubbqAlwz2VSVunD2tOplHyMUrtCtObAfVDUAhCndKaA9gApgfb3xw1IKbuQ1u4IF1FJl3VtumfQn//LiH1B3rXhcdyo3/vIttEk48RakUKClU8CgYEAzV7W3COOlDDcQd935DdtKBFRAPRPAlspQUnzMi5eSHMD/ISLDY5IiQHbIH83D4bvXq0X7qQoSBSNP7Dvv3HYuqMhf0DaegrlBuJllFVVq9qPVRnKxt1Il2HgxOBvbhOT+9in1BzA+YJ99UzC85O0Qz06A+CmtHEy4aZ2kj5hHjECgYEAmNS4+A8Fkss8Js1RieK2LniBxMgmYml3pfVLKGnzmng7H2+cwPLhPIzIuwytXywh2bzbsYEfYx3EoEVgMEpPhoarQnYPukrJO4gwE2o5Te6T5mJSZGlQJQj9q4ZB2Dfzet6INsK0oG8XVGXSpQvQh3RUYekCZQkBBFcpqWpbIEsCgYAnM3DQf3FJoSnXaMhrVBIovic5l0xFkEHskAjFTevO86Fsz1C2aSeRKSqGFoOQ0tmJzBEs1R6KqnHInicDTQrKhArgLXX4v3CddjfTRJkFWDbE/CkvKZNOrcf1nhaGCPspRJj2KUkj1Fhl9Cncdn/RsYEONbwQSjIfMPkvxF+8HQ==" - public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u+qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyehkd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdgcKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmwIDAQAB" - storage: - type: local - private: false - -spring: - flyway: - enabled: true - clean-disabled: false - datasource: - driver-class-name: org.h2.Driver - url: "jdbc:h2:mem:test;MODE=POSTGRESQL;DB_CLOSE_DELAY=-1;CASE_INSENSITIVE_IDENTIFIERS=true;TRACE_LEVEL_FILE=4;" - username: "" - password: - data: - mongodb: - auto-index-creation: true - host: localhost - port: 27017 - database: hideout-integration-test - h2: - console: - enabled: true - -# exposed: -# generate-ddl: true -# excluded-packages: dev.usbharu.hideout.core.infrastructure.kjobexposed -server: - port: 8080 diff --git a/hideout-core/src/intTest/resources/junit-platform.properties b/hideout-core/src/intTest/resources/junit-platform.properties deleted file mode 100644 index acfa9e5a..00000000 --- a/hideout-core/src/intTest/resources/junit-platform.properties +++ /dev/null @@ -1,2 +0,0 @@ -junit.jupiter.testclass.order.default=org.junit.jupiter.api.ClassOrderer$Random -junit.jupiter.testmethod.order.default=org.junit.jupiter.api.MethodOrderer$Random diff --git a/hideout-core/src/intTest/resources/logback.xml b/hideout-core/src/intTest/resources/logback.xml deleted file mode 100644 index a8bb21c4..00000000 --- a/hideout-core/src/intTest/resources/logback.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{x-request-id}] %logger{36} - %msg%n - - - - - - - diff --git a/hideout-core/src/intTest/resources/media/400x400.png b/hideout-core/src/intTest/resources/media/400x400.png deleted file mode 100644 index 0d2e71be..00000000 Binary files a/hideout-core/src/intTest/resources/media/400x400.png and /dev/null differ diff --git a/hideout-core/src/intTest/resources/sql/accounts/apiV1AccountsIdFollowPost フォローできる.sql b/hideout-core/src/intTest/resources/sql/accounts/apiV1AccountsIdFollowPost フォローできる.sql deleted file mode 100644 index a2b01c22..00000000 --- a/hideout-core/src/intTest/resources/sql/accounts/apiV1AccountsIdFollowPost フォローできる.sql +++ /dev/null @@ -1,17 +0,0 @@ -insert into "actors" (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, - created_at, key_id, following, followers, instance, locked, following_count, followers_count, - posts_count, last_post_at) -VALUES (3733363, 'follow-test-user-1', 'example.com', 'follow-test-user-1-name', '', - 'https://example.com/users/follow-test-user-1/inbox', - 'https://example.com/users/follow-test-user-1/outbox', 'https://example.com/users/follow-test-user-1', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678, - 'https://example.com/users/follow-test-user-1#pubkey', 'https://example.com/users/follow-test-user-1/following', - 'https://example.com/users/follow-test-user-1/followers', 0, false, 0, 0, 0, null), - (37335363, 'follow-test-user-2', 'example.com', 'follow-test-user-2-name', '', - 'https://example.com/users/follow-test-user-2/inbox', - 'https://example.com/users/follow-test-user-2/outbox', 'https://example.com/users/follow-test-user-2', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678, - 'https://example.com/users/follow-test-user-2#pubkey', 'https://example.com/users/follow-test-user-2/following', - 'https://example.com/users/follow-test-user-2/followers', 0, false, 0, 0, 0, null); diff --git a/hideout-core/src/intTest/resources/sql/accounts/test-accounts-statuses.sql b/hideout-core/src/intTest/resources/sql/accounts/test-accounts-statuses.sql deleted file mode 100644 index 10352e07..00000000 --- a/hideout-core/src/intTest/resources/sql/accounts/test-accounts-statuses.sql +++ /dev/null @@ -1,202 +0,0 @@ -insert into posts (id, actor_id, overview, content, text, created_at, visibility, url, repost_id, reply_id, sensitive, - ap_id, deleted) -VALUES (1, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/1', - null, null, false, 'https://example.com/users/1/posts/1', false), - (2, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/2', - null, 1, false, 'https://example.com/users/1/posts/2', false), - (3, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/3', - null, null, false, 'https://example.com/users/1/posts/3', false), - (4, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/4', - null, 3, false, 'https://example.com/users/1/posts/4', false), - (5, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/5', - null, null, false, 'https://example.com/users/1/posts/5', false), - (6, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/6', - null, null, false, 'https://example.com/users/1/posts/6', false), - (7, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/7', - null, null, false, 'https://example.com/users/1/posts/7', false), - (8, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/8', - null, 7, false, 'https://example.com/users/1/posts/8', false), - (9, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/9', - null, null, false, 'https://example.com/users/1/posts/9', false), - (10, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/10', - null, 9, false, 'https://example.com/users/1/posts/10', false), - (11, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/11', - null, null, false, 'https://example.com/users/1/posts/11', false), - (12, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/12', - null, null, false, 'https://example.com/users/1/posts/12', false), - (13, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/13', - null, null, false, 'https://example.com/users/1/posts/13', false), - (14, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/14', - null, 13, false, 'https://example.com/users/1/posts/14', false), - (15, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/15', - null, null, false, 'https://example.com/users/1/posts/15', false), - (16, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/16', - null, 15, false, 'https://example.com/users/1/posts/16', false), - (17, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/17', - null, null, false, 'https://example.com/users/1/posts/17', false), - (18, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/18', - null, null, false, 'https://example.com/users/1/posts/18', false), - (19, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/19', - null, null, false, 'https://example.com/users/1/posts/19', false), - (20, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/20', - null, 19, false, 'https://example.com/users/1/posts/20', false), - (21, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/21', - null, null, false, 'https://example.com/users/1/posts/21', false), - (22, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/22', - null, 21, false, 'https://example.com/users/1/posts/22', false), - (23, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/23', - null, null, false, 'https://example.com/users/1/posts/23', false), - (24, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/24', - null, null, false, 'https://example.com/users/1/posts/24', false), - (25, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/25', - null, null, false, 'https://example.com/users/1/posts/25', false), - (26, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/26', - null, 25, false, 'https://example.com/users/1/posts/26', false), - (27, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/27', - null, null, false, 'https://example.com/users/1/posts/27', false), - (28, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/28', - null, 27, false, 'https://example.com/users/1/posts/28', false), - (29, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/29', - null, null, false, 'https://example.com/users/1/posts/29', false), - (30, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/30', - null, null, false, 'https://example.com/users/1/posts/30', false), - (31, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/31', - null, null, false, 'https://example.com/users/1/posts/31', false), - (32, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/32', - null, 31, false, 'https://example.com/users/1/posts/32', false), - (33, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/33', - null, null, false, 'https://example.com/users/1/posts/33', false), - (34, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/34', - null, 33, false, 'https://example.com/users/1/posts/34', false), - (35, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/35', - null, null, false, 'https://example.com/users/1/posts/35', false), - (36, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/36', - null, null, false, 'https://example.com/users/1/posts/36', false), - (37, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/37', - null, null, false, 'https://example.com/users/1/posts/37', false), - (38, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/38', - null, 37, false, 'https://example.com/users/1/posts/38', false), - (39, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/39', - null, null, false, 'https://example.com/users/1/posts/39', false), - (40, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/40', - null, 39, false, 'https://example.com/users/1/posts/40', false), - (41, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/41', - null, null, false, 'https://example.com/users/1/posts/41', false), - (42, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/42', - null, null, false, 'https://example.com/users/1/posts/42', false), - (43, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/43', - null, null, false, 'https://example.com/users/1/posts/43', false), - (44, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/44', - null, 43, false, 'https://example.com/users/1/posts/44', false), - (45, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/45', - null, null, false, 'https://example.com/users/1/posts/45', false), - (46, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/46', - null, 45, false, 'https://example.com/users/1/posts/46', false), - (47, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/47', - null, null, false, 'https://example.com/users/1/posts/47', false), - (48, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/48', - null, null, false, 'https://example.com/users/1/posts/48', false), - (49, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/49', - null, null, false, 'https://example.com/users/1/posts/49', false), - (50, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/50', - null, 49, false, 'https://example.com/users/1/posts/50', false), - (51, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/51', - null, null, false, 'https://example.com/users/1/posts/51', false), - (52, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/52', - null, 51, false, 'https://example.com/users/1/posts/52', false), - (53, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/53', - null, null, false, 'https://example.com/users/1/posts/53', false), - (54, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/54', - null, null, false, 'https://example.com/users/1/posts/54', false), - (55, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/55', - null, null, false, 'https://example.com/users/1/posts/55', false), - (56, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/56', - null, 55, false, 'https://example.com/users/1/posts/56', false), - (57, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/57', - null, null, false, 'https://example.com/users/1/posts/57', false), - (58, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/58', - null, 57, false, 'https://example.com/users/1/posts/58', false), - (59, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/59', - null, null, false, 'https://example.com/users/1/posts/59', false), - (60, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/60', - null, null, false, 'https://example.com/users/1/posts/60', false), - (61, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/61', - null, null, false, 'https://example.com/users/1/posts/61', false), - (62, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/62', - null, 61, false, 'https://example.com/users/1/posts/62', false), - (63, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/63', - null, null, false, 'https://example.com/users/1/posts/63', false), - (64, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/64', - null, 63, false, 'https://example.com/users/1/posts/64', false), - (65, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/65', - null, null, false, 'https://example.com/users/1/posts/65', false), - (66, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/66', - null, null, false, 'https://example.com/users/1/posts/66', false), - (67, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/67', - null, null, false, 'https://example.com/users/1/posts/67', false), - (68, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/68', - null, 67, false, 'https://example.com/users/1/posts/68', false), - (69, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/69', - null, null, false, 'https://example.com/users/1/posts/69', false), - (70, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/70', - null, 69, false, 'https://example.com/users/1/posts/70', false), - (71, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/71', - null, null, false, 'https://example.com/users/1/posts/71', false), - (72, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/72', - null, null, false, 'https://example.com/users/1/posts/72', false), - (73, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/73', - null, null, false, 'https://example.com/users/1/posts/73', false), - (74, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/74', - null, 73, false, 'https://example.com/users/1/posts/74', false), - (75, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/75', - null, null, false, 'https://example.com/users/1/posts/75', false), - (76, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/76', - null, 75, false, 'https://example.com/users/1/posts/76', false), - (77, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/77', - null, null, false, 'https://example.com/users/1/posts/77', false), - (78, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/78', - null, null, false, 'https://example.com/users/1/posts/78', false), - (79, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/79', - null, null, false, 'https://example.com/users/1/posts/79', false), - (80, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/80', - null, 79, false, 'https://example.com/users/1/posts/80', false), - (81, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/81', - null, null, false, 'https://example.com/users/1/posts/81', false), - (82, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/82', - null, 81, false, 'https://example.com/users/1/posts/82', false), - (83, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/83', - null, null, false, 'https://example.com/users/1/posts/83', false), - (84, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/84', - null, null, false, 'https://example.com/users/1/posts/84', false), - (85, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/85', - null, null, false, 'https://example.com/users/1/posts/85', false), - (86, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/86', - null, 85, false, 'https://example.com/users/1/posts/86', false), - (87, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/87', - null, null, false, 'https://example.com/users/1/posts/87', false), - (88, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/88', - null, 87, false, 'https://example.com/users/1/posts/88', false), - (89, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/89', - null, null, false, 'https://example.com/users/1/posts/89', false), - (90, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/90', - null, null, false, 'https://example.com/users/1/posts/90', false), - (91, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/91', - null, null, false, 'https://example.com/users/1/posts/91', false), - (92, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/92', - null, 91, false, 'https://example.com/users/1/posts/92', false), - (93, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/93', - null, null, false, 'https://example.com/users/1/posts/93', false), - (94, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/94', - null, 93, false, 'https://example.com/users/1/posts/94', false), - (95, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/95', - null, null, false, 'https://example.com/users/1/posts/95', false), - (96, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/96', - null, null, false, 'https://example.com/users/1/posts/96', false), - (97, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/97', - null, null, false, 'https://example.com/users/1/posts/97', false), - (98, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/98', - null, 97, false, 'https://example.com/users/1/posts/98', false), - (99, 1, null, '

this is test

', 'this is test', 1706684146436, 2, 'https://example.com/users/1/posts/99', - null, null, false, 'https://example.com/users/1/posts/99', false), - (100, 1, null, '

this is test

', 'this is test', 1706684146436, 0, 'https://example.com/users/1/posts/100', - null, 99, false, 'https://example.com/users/1/posts/100', false); \ No newline at end of file diff --git a/hideout-core/src/intTest/resources/sql/filter/test-filter.sql b/hideout-core/src/intTest/resources/sql/filter/test-filter.sql deleted file mode 100644 index d06d6bc0..00000000 --- a/hideout-core/src/intTest/resources/sql/filter/test-filter.sql +++ /dev/null @@ -1,4 +0,0 @@ -insert into filters (id, user_id, name, context, action) -VALUES (1, 1, 'test filter', 'home', 'warn'); -insert into filter_keywords(id, filter_id, keyword, mode) -VALUES (1, 1, 'hoge', 'NONE') \ No newline at end of file diff --git a/hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがfollowers投稿を取得できる.sql b/hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがfollowers投稿を取得できる.sql deleted file mode 100644 index dc2ab9f1..00000000 --- a/hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがfollowers投稿を取得できる.sql +++ /dev/null @@ -1,28 +0,0 @@ -insert into "actors" (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, - created_at, key_id, following, followers, instance, locked, following_count, followers_count, - posts_count, last_post_at) -VALUES (8, 'test-user8', 'example.com', 'Im test-user8.', 'THis account is test-user8.', - 'https://example.com/users/test-user8/inbox', - 'https://example.com/users/test-user8/outbox', 'https://example.com/users/test-user8', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678, - 'https://example.com/users/test-user8#pubkey', 'https://example.com/users/test-user8/following', - 'https://example.com/users/test-user8/followers', 0, false, 0, 0, 0, null), - (9, 'test-user9', 'follower.example.com', 'Im test-user9.', 'THis account is test-user9.', - 'https://follower.example.com/users/test-user9/inbox', - 'https://follower.example.com/users/test-user9/outbox', 'https://follower.example.com/users/test-user9', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - null, 12345678, - 'https://follower.example.com/users/test-user9#pubkey', - 'https://follower.example.com/users/test-user9/following', - 'https://follower.example.com/users/test-user9/followers', 0, false, 0, 0, 0, null); - -insert into relationships (actor_id, target_actor_id, following, blocking, muting, follow_request, - ignore_follow_request) -VALUES (9, 8, true, false, false, false, false); - -insert into POSTS (ID, ACTOR_ID, OVERVIEW, CONTENT, TEXT, CREATED_AT, VISIBILITY, URL, REPLY_ID, REPOST_ID, SENSITIVE, - AP_ID) -VALUES (1239, 8, null, '

test post

', 'test post', 12345680, 2, 'https://example.com/users/test-user8/posts/1239', - null, null, false, - 'https://example.com/users/test-user8/posts/1239'); diff --git a/hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがpublic投稿を取得できる.sql b/hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがpublic投稿を取得できる.sql deleted file mode 100644 index a44861f4..00000000 --- a/hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがpublic投稿を取得できる.sql +++ /dev/null @@ -1,29 +0,0 @@ -insert into "actors" (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, - created_at, key_id, following, followers, instance, locked, following_count, followers_count, - posts_count, last_post_at) -VALUES (4, 'test-user4', 'example.com', 'Im test user4.', 'THis account is test user4.', - 'https://example.com/users/test-user4/inbox', - 'https://example.com/users/test-user4/outbox', 'https://example.com/users/test-user4', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678, - 'https://example.com/users/test-user4#pubkey', 'https://example.com/users/test-user4/following', - 'https://example.com/users/test-user4/followers', 0, false, 0, 0, 0, null), - (5, 'test-user5', 'follower.example.com', 'Im test user5.', 'THis account is test user5.', - 'https://follower.example.com/users/test-user5/inbox', - 'https://follower.example.com/users/test-user5/outbox', 'https://follower.example.com/users/test-user5', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - null, 12345678, - 'https://follower.example.com/users/test-user5#pubkey', - 'https://follower.example.com/users/test-user5/following', - 'https://follower.example.com/users/test-user5/followers', 0, false, 0, 0, 0, null); - -insert into relationships (actor_id, target_actor_id, following, blocking, muting, follow_request, - ignore_follow_request) -VALUES (5, 4, true, false, false, false, false); - -insert into POSTS (ID, "actor_id", OVERVIEW, CONTENT, TEXT, "created_at", VISIBILITY, URL, "repost_id", "reply_id", - SENSITIVE, - AP_ID) -VALUES (1237, 4, null, '

test post

', 'test post', 12345680, 0, 'https://example.com/users/test-user4/posts/1237', - null, null, false, - 'https://example.com/users/test-user4/posts/1237'); diff --git a/hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがunlisted投稿を取得できる.sql b/hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがunlisted投稿を取得できる.sql deleted file mode 100644 index 77cb3395..00000000 --- a/hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがunlisted投稿を取得できる.sql +++ /dev/null @@ -1,29 +0,0 @@ -insert into "actors" (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, - created_at, key_id, following, followers, instance, locked, following_count, followers_count, - posts_count, last_post_at) -VALUES (6, 'test-user6', 'example.com', 'Im test-user6.', 'THis account is test-user6.', - 'https://example.com/users/test-user6/inbox', - 'https://example.com/users/test-user6/outbox', 'https://example.com/users/test-user6', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678, - 'https://example.com/users/test-user6#pubkey', 'https://example.com/users/test-user6/following', - 'https://example.com/users/test-user6/followers', 0, false, 0, 0, 0, null), - (7, 'test-user7', 'follower.example.com', 'Im test-user7.', 'THis account is test-user7.', - 'https://follower.example.com/users/test-user7/inbox', - 'https://follower.example.com/users/test-user7/outbox', 'https://follower.example.com/users/test-user7', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - null, 12345678, - 'https://follower.example.com/users/test-user7#pubkey', - 'https://follower.example.com/users/test-user7/following', - 'https://follower.example.com/users/test-user7/followers', 0, false, 0, 0, 0, null); - -insert into relationships (actor_id, target_actor_id, following, blocking, muting, follow_request, - ignore_follow_request) -VALUES (7, 6, true, false, false, false, false); - -insert into POSTS (ID, "actor_ID", OVERVIEW, CONTENT, TEXT, "CREATED_AT", VISIBILITY, URL, "REPOST_ID", "REPLY_ID", - SENSITIVE, - AP_ID) -VALUES (1238, 6, null, '

test post

', 'test post', 12345680, 1, 'https://example.com/users/test-user6/posts/1238', - null, null, false, - 'https://example.com/users/test-user6/posts/1238'); diff --git a/hideout-core/src/intTest/resources/sql/note/メディア付き投稿はattachmentにDocumentとして画像が存在する.sql b/hideout-core/src/intTest/resources/sql/note/メディア付き投稿はattachmentにDocumentとして画像が存在する.sql deleted file mode 100644 index 6cc9db8c..00000000 --- a/hideout-core/src/intTest/resources/sql/note/メディア付き投稿はattachmentにDocumentとして画像が存在する.sql +++ /dev/null @@ -1,25 +0,0 @@ -insert into "actors" (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, - created_at, key_id, following, followers, instance, locked, following_count, followers_count, - posts_count, last_post_at) -VALUES (11, 'test-user11', 'example.com', 'Im test-user11.', 'THis account is test-user11.', - 'https://example.com/users/test-user11/inbox', - 'https://example.com/users/test-user11/outbox', 'https://example.com/users/test-user11', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678, - 'https://example.com/users/test-user11#pubkey', 'https://example.com/users/test-user11/following', - 'https://example.com/users/test-user11/followers', 0, false, 0, 0, 0, null); - -insert into POSTS (id, actor_id, overview, content, text, created_at, visibility, url, repost_id, reply_id, sensitive, - ap_id, - deleted) -VALUES (1242, 11, null, '

test post

', 'test post', 12345680, 0, - 'https://example.com/users/test-user11/posts/1242', null, null, false, - 'https://example.com/users/test-user11/posts/1242', false); - -insert into MEDIA (ID, NAME, URL, REMOTE_URL, THUMBNAIL_URL, TYPE, BLURHASH, MIME_TYPE, DESCRIPTION) -VALUES (1, 'test-media', 'https://example.com/media/test-media.png', null, null, 0, null, 'image/png', null), - (2, 'test-media2', 'https://example.com/media/test-media2.png', null, null, 0, null, 'image/png', null); - -insert into POSTS_MEDIA(POST_ID, MEDIA_ID) -VALUES (1242, 1), - (1242, 2); diff --git a/hideout-core/src/intTest/resources/sql/note/リプライになっている投稿はinReplyToが存在する.sql b/hideout-core/src/intTest/resources/sql/note/リプライになっている投稿はinReplyToが存在する.sql deleted file mode 100644 index 41ac73a4..00000000 --- a/hideout-core/src/intTest/resources/sql/note/リプライになっている投稿はinReplyToが存在する.sql +++ /dev/null @@ -1,20 +0,0 @@ -insert into "actors" (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, - created_at, key_id, following, followers, instance, locked, following_count, followers_count, - posts_count, last_post_at) -VALUES (10, 'test-user10', 'example.com', 'Im test-user10.', 'THis account is test-user10.', - 'https://example.com/users/test-user10/inbox', - 'https://example.com/users/test-user10/outbox', 'https://example.com/users/test-user10', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678, - 'https://example.com/users/test-user10#pubkey', 'https://example.com/users/test-user10/following', - 'https://example.com/users/test-user10/followers', 0, false, 0, 0, 0, null); - -insert into POSTS (id, actor_id, overview, content, text, created_at, visibility, url, repost_id, reply_id, sensitive, - ap_id, - deleted) -VALUES (1240, 10, null, '

test post

', 'test post', 12345680, 0, - 'https://example.com/users/test-user10/posts/1240', null, null, false, - 'https://example.com/users/test-user10/posts/1240', false), - (1241, 10, null, '

test post

', 'test post', 12345680, 0, - 'https://example.com/users/test-user10/posts/1241', null, 1240, false, - 'https://example.com/users/test-user10/posts/1241', false); diff --git a/hideout-core/src/intTest/resources/sql/note/匿名でfollowers投稿を取得しようとすると404.sql b/hideout-core/src/intTest/resources/sql/note/匿名でfollowers投稿を取得しようとすると404.sql deleted file mode 100644 index 250cfb5a..00000000 --- a/hideout-core/src/intTest/resources/sql/note/匿名でfollowers投稿を取得しようとすると404.sql +++ /dev/null @@ -1,17 +0,0 @@ -insert into "actors" (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, - created_at, key_id, following, followers, instance, locked, following_count, followers_count, - posts_count, last_post_at) -VALUES (3, 'test-user3', 'example.com', 'Im test user3.', 'THis account is test user3.', - 'https://example.com/users/test-user3/inbox', - 'https://example.com/users/test-user3/outbox', 'https://example.com/users/test-user3', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678, - 'https://example.com/users/test-user3#pubkey', 'https://example.com/users/test-user3/following', - 'https://example.com/users/test-user3/followers', 0, false, 0, 0, 0, null); - -insert into POSTS (id, actor_id, overview, content, text, created_at, visibility, url, repost_id, reply_id, sensitive, - ap_id, - deleted) -VALUES (1236, 3, null, '

test post

', 'test post', 12345680, 2, 'https://example.com/users/test-user3/posts/1236', - null, null, false, - 'https://example.com/users/test-user3/posts/1236', false) diff --git a/hideout-core/src/intTest/resources/sql/note/匿名でpublic投稿を取得できる.sql b/hideout-core/src/intTest/resources/sql/note/匿名でpublic投稿を取得できる.sql deleted file mode 100644 index 777f9244..00000000 --- a/hideout-core/src/intTest/resources/sql/note/匿名でpublic投稿を取得できる.sql +++ /dev/null @@ -1,17 +0,0 @@ -insert into actors (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, created_at, - key_id, following, followers, instance, locked, following_count, followers_count, posts_count, - last_post_at) -VALUES (1, 'test-user', 'example.com', 'Im test user.', 'THis account is test user.', - 'https://example.com/users/test-user/inbox', - 'https://example.com/users/test-user/outbox', 'https://example.com/users/test-user', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678, - 'https://example.com/users/test-user#pubkey', 'https://example.com/users/test-user/following', - 'https://example.com/users/test-users/followers', 0, false, 0, 0, 0, null); - -insert into POSTS (id, actor_id, overview, content, text, created_at, visibility, url, repost_id, reply_id, sensitive, - ap_id, - deleted) -VALUES (1234, 1, null, '

test post

', 'test post', 12345680, 0, 'https://example.com/users/test-user/posts/1234', - null, null, false, - 'https://example.com/users/test-user/posts/1234', false) diff --git a/hideout-core/src/intTest/resources/sql/note/匿名でunlisted投稿を取得できる.sql b/hideout-core/src/intTest/resources/sql/note/匿名でunlisted投稿を取得できる.sql deleted file mode 100644 index b132734d..00000000 --- a/hideout-core/src/intTest/resources/sql/note/匿名でunlisted投稿を取得できる.sql +++ /dev/null @@ -1,17 +0,0 @@ -insert into actors (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, created_at, - key_id, following, followers, instance, locked, following_count, followers_count, posts_count, - last_post_at) -VALUES (2, 'test-user2', 'example.com', 'Im test user2.', 'THis account is test user2.', - 'https://example.com/users/test-user2/inbox', - 'https://example.com/users/test-user2/outbox', 'https://example.com/users/test-user2', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678, - 'https://example.com/users/test-user2#pubkey', 'https://example.com/users/test-user2/following', - 'https://example.com/users/test-user2/followers', 0, false, 0, 0, 0, null); - -insert into POSTS (id, actor_id, overview, content, text, created_at, visibility, url, repost_id, reply_id, sensitive, - ap_id, - deleted) -VALUES (1235, 2, null, '

test post

', 'test post', 12345680, 1, 'https://example.com/users/test-user2/posts/1235', - null, null, false, - 'https://example.com/users/test-user2/posts/1235', false) diff --git a/hideout-core/src/intTest/resources/sql/notification/test-mastodon_notifications.sql b/hideout-core/src/intTest/resources/sql/notification/test-mastodon_notifications.sql deleted file mode 100644 index c97a25a7..00000000 --- a/hideout-core/src/intTest/resources/sql/notification/test-mastodon_notifications.sql +++ /dev/null @@ -1,66 +0,0 @@ -insert into mastodon_notifications (id, user_id, type, created_at, account_id, status_id, report_id, relationship_serverance_event_id) -values (1, 1, 'follow', current_timestamp, 2, null, null, null), - (2, 1, 'follow', current_timestamp, 2, null, null, null), - (3, 1, 'follow', current_timestamp, 2, null, null, null), - (4, 1, 'follow', current_timestamp, 2, null, null, null), - (5, 1, 'follow', current_timestamp, 2, null, null, null), - (6, 1, 'follow', current_timestamp, 2, null, null, null), - (7, 1, 'follow', current_timestamp, 2, null, null, null), - (8, 1, 'follow', current_timestamp, 2, null, null, null), - (9, 1, 'follow', current_timestamp, 2, null, null, null), - (10, 1, 'follow', current_timestamp, 2, null, null, null), - (11, 1, 'follow', current_timestamp, 2, null, null, null), - (12, 1, 'follow', current_timestamp, 2, null, null, null), - (13, 1, 'follow', current_timestamp, 2, null, null, null), - (14, 1, 'follow', current_timestamp, 2, null, null, null), - (15, 1, 'follow', current_timestamp, 2, null, null, null), - (16, 1, 'follow', current_timestamp, 2, null, null, null), - (17, 1, 'follow', current_timestamp, 2, null, null, null), - (18, 1, 'follow', current_timestamp, 2, null, null, null), - (19, 1, 'follow', current_timestamp, 2, null, null, null), - (20, 1, 'follow', current_timestamp, 2, null, null, null), - (21, 1, 'follow', current_timestamp, 2, null, null, null), - (22, 1, 'follow', current_timestamp, 2, null, null, null), - (23, 1, 'follow', current_timestamp, 2, null, null, null), - (24, 1, 'follow', current_timestamp, 2, null, null, null), - (25, 1, 'follow', current_timestamp, 2, null, null, null), - (26, 1, 'follow', current_timestamp, 2, null, null, null), - (27, 1, 'follow', current_timestamp, 2, null, null, null), - (28, 1, 'follow', current_timestamp, 2, null, null, null), - (29, 1, 'follow', current_timestamp, 2, null, null, null), - (30, 1, 'follow', current_timestamp, 2, null, null, null), - (31, 1, 'follow', current_timestamp, 2, null, null, null), - (32, 1, 'follow', current_timestamp, 2, null, null, null), - (33, 1, 'follow', current_timestamp, 2, null, null, null), - (34, 1, 'follow', current_timestamp, 2, null, null, null), - (35, 1, 'follow', current_timestamp, 2, null, null, null), - (36, 1, 'follow', current_timestamp, 2, null, null, null), - (37, 1, 'follow', current_timestamp, 2, null, null, null), - (38, 1, 'follow', current_timestamp, 2, null, null, null), - (39, 1, 'follow', current_timestamp, 2, null, null, null), - (40, 1, 'follow', current_timestamp, 2, null, null, null), - (41, 1, 'follow', current_timestamp, 2, null, null, null), - (42, 1, 'follow', current_timestamp, 2, null, null, null), - (43, 1, 'follow', current_timestamp, 2, null, null, null), - (44, 1, 'follow', current_timestamp, 2, null, null, null), - (45, 1, 'follow', current_timestamp, 2, null, null, null), - (46, 1, 'follow', current_timestamp, 2, null, null, null), - (47, 1, 'follow', current_timestamp, 2, null, null, null), - (48, 1, 'follow', current_timestamp, 2, null, null, null), - (49, 1, 'follow', current_timestamp, 2, null, null, null), - (50, 1, 'follow', current_timestamp, 2, null, null, null), - (51, 1, 'follow', current_timestamp, 2, null, null, null), - (52, 1, 'follow', current_timestamp, 2, null, null, null), - (53, 1, 'follow', current_timestamp, 2, null, null, null), - (54, 1, 'follow', current_timestamp, 2, null, null, null), - (55, 1, 'follow', current_timestamp, 2, null, null, null), - (56, 1, 'follow', current_timestamp, 2, null, null, null), - (57, 1, 'follow', current_timestamp, 2, null, null, null), - (58, 1, 'follow', current_timestamp, 2, null, null, null), - (59, 1, 'follow', current_timestamp, 2, null, null, null), - (60, 1, 'follow', current_timestamp, 2, null, null, null), - (61, 1, 'follow', current_timestamp, 2, null, null, null), - (62, 1, 'follow', current_timestamp, 2, null, null, null), - (63, 1, 'follow', current_timestamp, 2, null, null, null), - (64, 1, 'follow', current_timestamp, 2, null, null, null), - (65, 1, 'follow', current_timestamp, 2, null, null, null); \ No newline at end of file diff --git a/hideout-core/src/intTest/resources/sql/notification/test-notifications.sql b/hideout-core/src/intTest/resources/sql/notification/test-notifications.sql deleted file mode 100644 index 38982603..00000000 --- a/hideout-core/src/intTest/resources/sql/notification/test-notifications.sql +++ /dev/null @@ -1,66 +0,0 @@ -insert into notifications(id, type, user_id, source_actor_id, post_id, text, reaction_id, created_at) -VALUES (1, 'follow', 1, 2, null, null, null, current_timestamp), - (2, 'follow', 1, 2, null, null, null, current_timestamp), - (3, 'follow', 1, 2, null, null, null, current_timestamp), - (4, 'follow', 1, 2, null, null, null, current_timestamp), - (5, 'follow', 1, 2, null, null, null, current_timestamp), - (6, 'follow', 1, 2, null, null, null, current_timestamp), - (7, 'follow', 1, 2, null, null, null, current_timestamp), - (8, 'follow', 1, 2, null, null, null, current_timestamp), - (9, 'follow', 1, 2, null, null, null, current_timestamp), - (10, 'follow', 1, 2, null, null, null, current_timestamp), - (11, 'follow', 1, 2, null, null, null, current_timestamp), - (12, 'follow', 1, 2, null, null, null, current_timestamp), - (13, 'follow', 1, 2, null, null, null, current_timestamp), - (14, 'follow', 1, 2, null, null, null, current_timestamp), - (15, 'follow', 1, 2, null, null, null, current_timestamp), - (16, 'follow', 1, 2, null, null, null, current_timestamp), - (17, 'follow', 1, 2, null, null, null, current_timestamp), - (18, 'follow', 1, 2, null, null, null, current_timestamp), - (19, 'follow', 1, 2, null, null, null, current_timestamp), - (20, 'follow', 1, 2, null, null, null, current_timestamp), - (21, 'follow', 1, 2, null, null, null, current_timestamp), - (22, 'follow', 1, 2, null, null, null, current_timestamp), - (23, 'follow', 1, 2, null, null, null, current_timestamp), - (24, 'follow', 1, 2, null, null, null, current_timestamp), - (25, 'follow', 1, 2, null, null, null, current_timestamp), - (26, 'follow', 1, 2, null, null, null, current_timestamp), - (27, 'follow', 1, 2, null, null, null, current_timestamp), - (28, 'follow', 1, 2, null, null, null, current_timestamp), - (29, 'follow', 1, 2, null, null, null, current_timestamp), - (30, 'follow', 1, 2, null, null, null, current_timestamp), - (31, 'follow', 1, 2, null, null, null, current_timestamp), - (32, 'follow', 1, 2, null, null, null, current_timestamp), - (33, 'follow', 1, 2, null, null, null, current_timestamp), - (34, 'follow', 1, 2, null, null, null, current_timestamp), - (35, 'follow', 1, 2, null, null, null, current_timestamp), - (36, 'follow', 1, 2, null, null, null, current_timestamp), - (37, 'follow', 1, 2, null, null, null, current_timestamp), - (38, 'follow', 1, 2, null, null, null, current_timestamp), - (39, 'follow', 1, 2, null, null, null, current_timestamp), - (40, 'follow', 1, 2, null, null, null, current_timestamp), - (41, 'follow', 1, 2, null, null, null, current_timestamp), - (42, 'follow', 1, 2, null, null, null, current_timestamp), - (43, 'follow', 1, 2, null, null, null, current_timestamp), - (44, 'follow', 1, 2, null, null, null, current_timestamp), - (45, 'follow', 1, 2, null, null, null, current_timestamp), - (46, 'follow', 1, 2, null, null, null, current_timestamp), - (47, 'follow', 1, 2, null, null, null, current_timestamp), - (48, 'follow', 1, 2, null, null, null, current_timestamp), - (49, 'follow', 1, 2, null, null, null, current_timestamp), - (50, 'follow', 1, 2, null, null, null, current_timestamp), - (51, 'follow', 1, 2, null, null, null, current_timestamp), - (52, 'follow', 1, 2, null, null, null, current_timestamp), - (53, 'follow', 1, 2, null, null, null, current_timestamp), - (54, 'follow', 1, 2, null, null, null, current_timestamp), - (55, 'follow', 1, 2, null, null, null, current_timestamp), - (56, 'follow', 1, 2, null, null, null, current_timestamp), - (57, 'follow', 1, 2, null, null, null, current_timestamp), - (58, 'follow', 1, 2, null, null, null, current_timestamp), - (59, 'follow', 1, 2, null, null, null, current_timestamp), - (60, 'follow', 1, 2, null, null, null, current_timestamp), - (61, 'follow', 1, 2, null, null, null, current_timestamp), - (62, 'follow', 1, 2, null, null, null, current_timestamp), - (63, 'follow', 1, 2, null, null, null, current_timestamp), - (64, 'follow', 1, 2, null, null, null, current_timestamp), - (65, 'follow', 1, 2, null, null, null, current_timestamp); \ No newline at end of file diff --git a/hideout-core/src/intTest/resources/sql/test-custom-emoji.sql b/hideout-core/src/intTest/resources/sql/test-custom-emoji.sql deleted file mode 100644 index 83c2747a..00000000 --- a/hideout-core/src/intTest/resources/sql/test-custom-emoji.sql +++ /dev/null @@ -1,3 +0,0 @@ -insert into emojis(id, name, domain, instance_id, url, category, created_at) -VALUES (1, 'kotlin', 'example.com', null, 'https://example.com/emojis/kotlin', null, - TIMESTAMP '2024-01-08 07:51:30.036Z'); diff --git a/hideout-core/src/intTest/resources/sql/test-post.sql b/hideout-core/src/intTest/resources/sql/test-post.sql deleted file mode 100644 index cd623188..00000000 --- a/hideout-core/src/intTest/resources/sql/test-post.sql +++ /dev/null @@ -1,4 +0,0 @@ -insert into posts (id, actor_id, overview, content, text, created_at, visibility, url, repost_id, reply_id, sensitive, - ap_id) -VALUES (1, 1, null, '

test post

', 'hello', 1234455, 0, 'https://localhost/users/1/posts/1', null, null, false, - 'https://users/1/posts/1'); diff --git a/hideout-core/src/intTest/resources/sql/test-user.sql b/hideout-core/src/intTest/resources/sql/test-user.sql deleted file mode 100644 index d46e5280..00000000 --- a/hideout-core/src/intTest/resources/sql/test-user.sql +++ /dev/null @@ -1,10 +0,0 @@ -insert into "actors" (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, - created_at, key_id, following, followers, instance, locked, following_count, followers_count, - posts_count, last_post_at) -VALUES (1, 'test-user', 'example.com', 'Im test user.', 'THis account is test user.', - 'https://example.com/users/test-user/inbox', - 'https://example.com/users/test-user/outbox', 'https://example.com/users/test-user', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678, - 'https://example.com/users/test-user#pubkey', 'https://example.com/users/test-user/following', - 'https://example.com/users/test-users/followers', 0, false, 0, 0, 0, null); diff --git a/hideout-core/src/intTest/resources/sql/test-user2.sql b/hideout-core/src/intTest/resources/sql/test-user2.sql deleted file mode 100644 index 0f736704..00000000 --- a/hideout-core/src/intTest/resources/sql/test-user2.sql +++ /dev/null @@ -1,10 +0,0 @@ -insert into "actors" (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, - created_at, key_id, following, followers, instance, locked, following_count, followers_count, - posts_count, last_post_at) -VALUES (2, 'test-user2', 'example.com', 'Im test user.', 'THis account is test user.', - 'https://example.com/users/test-user2/inbox', - 'https://example.com/users/test-user2/outbox', 'https://example.com/users/test-user2', - '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----', - '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678, - 'https://example.com/users/test-user2#pubkey', 'https://example.com/users/test-user2/following', - 'https://example.com/users/test-user2s/followers', 0, false, 0, 0, 0, null); diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/media/Media.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/media/Media.kt new file mode 100644 index 00000000..04d1b2ee --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/media/Media.kt @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.application.media + +class Media diff --git a/hideout-core/src/intTest/kotlin/util/SpringApplicationTestBase.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/media/UploadMedia.kt similarity index 82% rename from hideout-core/src/intTest/kotlin/util/SpringApplicationTestBase.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/media/UploadMedia.kt index 158f8c7a..9f409416 100644 --- a/hideout-core/src/intTest/kotlin/util/SpringApplicationTestBase.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/media/UploadMedia.kt @@ -14,9 +14,8 @@ * limitations under the License. */ -package util +package dev.usbharu.hideout.core.application.media -import org.springframework.boot.test.context.SpringBootTest +import java.nio.file.Path -@SpringBootTest -abstract class SpringApplicationTestBase +data class UploadMedia(val path: Path) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/media/UploadMediaApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/media/UploadMediaApplicationService.kt new file mode 100644 index 00000000..36c07865 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/media/UploadMediaApplicationService.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.application.media + +import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.shared.CommandExecutor +import dev.usbharu.hideout.core.application.shared.Transaction +import org.slf4j.LoggerFactory + +class UploadMediaApplicationService(transaction: Transaction) : AbstractApplicationService( + transaction, logger +) { + companion object { + private val logger = LoggerFactory.getLogger(UploadMediaApplicationService::class.java) + } + + override suspend fun internalExecute(command: UploadMedia, executor: CommandExecutor): Media { + TODO() + } +} \ No newline at end of file diff --git a/hideout-core/src/intTest/kotlin/util/TestTransaction.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/media/MediaProcessor.kt similarity index 66% rename from hideout-core/src/intTest/kotlin/util/TestTransaction.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/media/MediaProcessor.kt index 0f8b6317..d2657985 100644 --- a/hideout-core/src/intTest/kotlin/util/TestTransaction.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/media/MediaProcessor.kt @@ -14,12 +14,10 @@ * limitations under the License. */ -package util +package dev.usbharu.hideout.core.external.media -import dev.usbharu.hideout.core.application.shared.Transaction +import java.nio.file.Path -object TestTransaction : Transaction { - override suspend fun transaction(block: suspend () -> T): T = block() - - override suspend fun transaction(transactionLevel: Int, block: suspend () -> T): T = block() -} +interface MediaProcessor { + suspend fun process(path: Path): ProcessedMedia +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/media/ProcessedMedia.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/media/ProcessedMedia.kt new file mode 100644 index 00000000..ac136c3c --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/media/ProcessedMedia.kt @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.external.media + +import dev.usbharu.hideout.core.domain.model.media.FileType +import dev.usbharu.hideout.core.domain.model.media.MimeType +import java.nio.file.Path + +data class ProcessedMedia( + val path: Path, + val thumbnailPath: Path?, + val fileType: FileType, + val mimeType: MimeType, + val blurHash: String, +) diff --git a/owl/gradle.properties b/owl/gradle.properties index e981646f..1108ef87 100644 --- a/owl/gradle.properties +++ b/owl/gradle.properties @@ -2,4 +2,6 @@ kotlin.code.style=official org.gradle.daemon=true org.gradle.parallel=true org.gradle.configureondemand=true -#ksp.useKSP2=true \ No newline at end of file +#ksp.useKSP2=true +org.gradle.configuration-cache=true +org.gradle.configuration-cache.problems=warn \ No newline at end of file diff --git a/owl/owl-common/owl-common-serialize-jackson/build.gradle.kts b/owl/owl-common/owl-common-serialize-jackson/build.gradle.kts index 5eed5b43..bb09a5e4 100644 --- a/owl/owl-common/owl-common-serialize-jackson/build.gradle.kts +++ b/owl/owl-common/owl-common-serialize-jackson/build.gradle.kts @@ -19,5 +19,5 @@ tasks.test { useJUnitPlatform() } kotlin { - jvmToolchain(21) + jvmToolchain(17) } \ No newline at end of file