From ef40b94b5ed6b9e2cd2cfc89efdaa8f8bcbe4c0d Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:32:10 +0900 Subject: [PATCH] =?UTF-8?q?test:=20e2e=E3=83=86=E3=82=B9=E3=83=88=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 2 + src/e2eTest/kotlin/KarateUtil.kt | 12 +++ src/e2eTest/kotlin/oauth2/OAuth2LoginTest.kt | 82 ++++++++----------- src/e2eTest/resources/karate-config.js | 25 ++++++ .../resources/oauth2/Oauth2LoginTest.feature | 32 ++++++++ src/e2eTest/resources/oauth2/test.feature | 9 ++ src/e2eTest/resources/oauth2/user.sql | 46 +++++++++++ 7 files changed, 158 insertions(+), 50 deletions(-) create mode 100644 src/e2eTest/kotlin/KarateUtil.kt create mode 100644 src/e2eTest/resources/karate-config.js create mode 100644 src/e2eTest/resources/oauth2/Oauth2LoginTest.feature create mode 100644 src/e2eTest/resources/oauth2/test.feature create mode 100644 src/e2eTest/resources/oauth2/user.sql diff --git a/build.gradle.kts b/build.gradle.kts index 002d9613..c8d31ca7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -233,6 +233,8 @@ dependencies { e2eTestImplementation("org.springframework.security:spring-security-test") e2eTestImplementation("org.springframework.boot:spring-boot-starter-webflux") e2eTestImplementation("org.jsoup:jsoup:1.17.1") + e2eTestImplementation("com.intuit.karate:karate-junit5:1.4.1") + diff --git a/src/e2eTest/kotlin/KarateUtil.kt b/src/e2eTest/kotlin/KarateUtil.kt new file mode 100644 index 00000000..e78e8510 --- /dev/null +++ b/src/e2eTest/kotlin/KarateUtil.kt @@ -0,0 +1,12 @@ +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") + } + } +} diff --git a/src/e2eTest/kotlin/oauth2/OAuth2LoginTest.kt b/src/e2eTest/kotlin/oauth2/OAuth2LoginTest.kt index 723f6f05..ba524c0d 100644 --- a/src/e2eTest/kotlin/oauth2/OAuth2LoginTest.kt +++ b/src/e2eTest/kotlin/oauth2/OAuth2LoginTest.kt @@ -1,67 +1,49 @@ package oauth2 +import KarateUtil +import com.intuit.karate.junit5.Karate import dev.usbharu.hideout.SpringApplication -import org.jsoup.Jsoup -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation -import org.junit.jupiter.api.Order -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.TestMethodOrder +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.http.MediaType -import org.springframework.test.web.reactive.server.WebTestClient -import org.springframework.web.reactive.function.BodyInserters +import org.springframework.boot.test.web.server.LocalServerPort +import org.springframework.test.context.jdbc.Sql @SpringBootTest( classes = [SpringApplication::class], webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, ) -@TestMethodOrder(OrderAnnotation::class) +@Sql("/oauth2/user.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) class OAuth2LoginTest { - @Autowired - private lateinit var webTestClient: WebTestClient + @LocalServerPort + private var port = "" - @Test - @Order(2) - fun アカウント作成() { - val returnResult = webTestClient.get() - .uri("/auth/sign_up") - .exchange() - .expectStatus() - .isOk - .returnResult(String::class.java) - - val html = returnResult - .responseBody - .toStream() - .toList() - .toList() - .joinToString("") - - val session = returnResult.responseCookies["JSESSIONID"]?.first()?.value!! - - val attr = Jsoup.parse(html).selectXpath("//input[@name=\"_csrf\"]").attr("value") - - println("CSRF TOKEN = $attr") - - webTestClient - .post() - .uri("/api/v1/accounts") - .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .body( - BodyInserters.fromFormData("username", "oatuh-login-test") - .with("password", "very-secure-password").with("_csrf", attr) - ) - .cookie("JSESSIONID", session) - .exchange() - .expectStatus().isFound - .expectCookie() + @Karate.Test + @TestFactory + fun test(): Karate = + Karate.run("test").scenarioName("invalid").relativeTo(javaClass).systemProperty("karate.port", port) + .karateEnv("dev") + @Karate.Test + @TestFactory + fun `スコープwrite readを持ったトークンの作成`(): Karate { + return KarateUtil.springBootKarateTest( + "Oauth2LoginTest", + "スコープwrite readを持ったトークンの作成", + javaClass, + port + ) } -// @Test -// fun `OAuth2で権限read writeを持ったトークンでのログインができる`() { -//// webTestClient.post().uri("/api/v1/apps") -// } + companion object { + @JvmStatic + @AfterAll + fun dropDatabase(@Autowired flyway: Flyway) { + flyway.clean() + flyway.migrate() + } + } } diff --git a/src/e2eTest/resources/karate-config.js b/src/e2eTest/resources/karate-config.js new file mode 100644 index 00000000..9fd5dd1e --- /dev/null +++ b/src/e2eTest/resources/karate-config.js @@ -0,0 +1,25 @@ +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') { + config = { + baseUrl: 'https://test-hideout.usbharu.dev' + } + } else if (env === 'dev') { + let port = karate.properties['karate.port'] || '8080' + config = { + baseUrl: 'http://localhost:' + port + } + } 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/src/e2eTest/resources/oauth2/Oauth2LoginTest.feature b/src/e2eTest/resources/oauth2/Oauth2LoginTest.feature new file mode 100644 index 00000000..29ae760c --- /dev/null +++ b/src/e2eTest/resources/oauth2/Oauth2LoginTest.feature @@ -0,0 +1,32 @@ +Feature: OAuth2 Login Test + + Background: + * url baseUrl + * configure driver = { type: 'chrome' } + + Scenario: スコープwrite readを持ったトークンの作成 + + * def apps = + """ + { + "client_name": "oauth2-test-client-1", + "redirect_uris": "https://example.com", + "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://example.com&client_id=' + client_id + '&scope=write read' + + Given driver authorizeEndpoint + And driver.input('#username','test-user') + And driver.input('#password','password') + When driver.submit().click('body > div > form > button') + Then match driver.title == 'test' diff --git a/src/e2eTest/resources/oauth2/test.feature b/src/e2eTest/resources/oauth2/test.feature new file mode 100644 index 00000000..7a801de8 --- /dev/null +++ b/src/e2eTest/resources/oauth2/test.feature @@ -0,0 +1,9 @@ +Feature: test + + Background: + * url baseUrl + + Scenario: test + Given path '/api/v1/apps' + When method get + Then status 401 diff --git a/src/e2eTest/resources/oauth2/user.sql b/src/e2eTest/resources/oauth2/user.sql new file mode 100644 index 00000000..15aa977f --- /dev/null +++ b/src/e2eTest/resources/oauth2/user.sql @@ -0,0 +1,46 @@ +insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY, + CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE) +VALUES (1730415786666758144, 'test-user', 'localhost', 'Im test user.', 'THis account is test user.', + '$2a$10$/mWC/n7nC7X3l9qCEOKnredxne2zewoqEsJWTOdlKfg2zXKJ0F9Em', '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', null);