@@ -0,0 +1,36 @@
|
||||
quarkus:
|
||||
http:
|
||||
port: 8083
|
||||
application:
|
||||
name: nowchess-account
|
||||
smallrye-openapi:
|
||||
info-title: NowChess Account Service
|
||||
path: /openapi
|
||||
swagger-ui:
|
||||
always-include: true
|
||||
path: /swagger-ui
|
||||
datasource:
|
||||
db-kind: h2
|
||||
username: sa
|
||||
password: ""
|
||||
jdbc:
|
||||
url: "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"
|
||||
hibernate-orm:
|
||||
schema-management:
|
||||
strategy: drop-and-create
|
||||
mp:
|
||||
jwt:
|
||||
verify:
|
||||
publickey:
|
||||
location: keys/test-public.pem
|
||||
issuer: nowchess
|
||||
smallrye:
|
||||
jwt:
|
||||
sign:
|
||||
key:
|
||||
location: keys/test-private.pem
|
||||
nowchess:
|
||||
internal:
|
||||
secret: test-secret
|
||||
auth:
|
||||
enabled: false
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC4zBHgRLMez2b6
|
||||
wfdvvTJVR8xxbr/kJUMiq4ot14KhtTaGikFW+77ezjoqabFWH7CNjDvASWCM2n7X
|
||||
PxL4fhUwzvTbhRZ2XNM80lKB+OIjP3hoNLvgeSNHbS4CztOfk2JVtQFLQdYJ/gvB
|
||||
oFPgBtZYO/SZVML28d5U92JrWRIC1e1Ht1oKwKJoOqtTJrs/RuOlKQ/du4kwY8m0
|
||||
jPw05wFA1YRMUC78xKklCVYCufYewIUTdKxATK0ZKWBoPCJnxDg8gwgpnV1wHQrH
|
||||
GcbZvhcVg3GWpDcYdnogV4rlssws57+uAhGRyQBkmmhVb+zT+LT7WXDPB46MnHkK
|
||||
FIZaxEkHAgMBAAECggEAAvu4Zih1w8+RWAb9mZ4yS9Im6MXi7yny1YJzbp4GC9pD
|
||||
ERT2TRMvV6V4puqh5EQKs55J8Ka+mkeEuLDZ+4z9hpYwucKCRFLnThoPHu4HqI4D
|
||||
wZroVY1fFm4aygzQucjFU6DibnaXn/2r7upJsFor56zAHCGULCxnbHO58QW1Frqa
|
||||
UrTndSkrxavBD9LL1ohPEy3saXlRCVAEM5l7jZbg52dPauIYAOv0e+EE3RETw/Xz
|
||||
3EWukIZ7PKyoyuQm8Sv2u7lyISljDGlvrW5IjVRPMPqOKNOa/pV3qU4mbUY6GjbC
|
||||
B4xt8kEKjVSkTeMXA+W0gnZddnQOtcQYSrYWWes+AQKBgQDzjmt1ZJktZG96M8+f
|
||||
Ov9JznfzSLYxN7EboDhqjTVBOkb6flRSYrd9E6gReIIrq5Sjs9Z+toA/u8BmjQ/P
|
||||
GTrrLVh6bLBicUGKcmQFKw/0D9lOlbxaMg8VO9rqSb/AslumJwjucU7DA+WAN52j
|
||||
cyiLiw+EmWjL/DV51fHHI18SgQKBgQDCPRzpeP8Qox83/+tGR/6fSSRi5ec3ZVPy
|
||||
aCCCZM6qqhLv3hJkV0djRruVVfe136PwUi20BW6aF0PXmxDIGRWqDLQGkvDNEhjw
|
||||
ZLBv/dYtW2HBZhq4E0w8DiaNZCOWvpLQ3QCEtzmuhyHhNqYHzvmuerk+w4c/8fY6
|
||||
DFyPyiAHhwKBgDrpO/zNNG/SV1SLq7CsKIvFsSXbdJY7Dk/MVVkQhs0cN4bnf6Xd
|
||||
0twiIQj4ySOfAPkHyt4jbqn70/H6NNS3GZVBBqG2IIPvORcvzBmj7Nvv6XQkq8Z1
|
||||
TUipja4V4JfPjHOIBZUHOzHYg26cBTk/5ZK7NCmyobKVcqnhofW1DI4BAoGAaRu4
|
||||
8X5QSCh9VEhggH+lAX0K+5l9LTTf4GUIcocqbp/p73M0cKfqMYatK3qBuSF0DS/r
|
||||
G2d1Gl1MkPeQdTddyc9l+8i4FcCdTjiuYWvy4kh49bbS7plCv5zIr+pod8JYoD13
|
||||
clnUFOV7J+vynHccFZbDd3tHTQsaOv9Fd2nhOzECgYEA8SWBEmTuaBh+0vr6zS+E
|
||||
wD+cwB3iaGo+7fP7TZ+v1kxoDlcDjPYM4ikiOB+OPGNkAfqc3MGsbhfgcxqD0+5r
|
||||
kpCFyiyieyoT+7hkMpMsJCNwFO+29fc3DDqPX4Keqp26tMxtRzYea3GtVShiRXew
|
||||
5i4ReFwm3/IWDn9kLmHT6Fg=
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -0,0 +1,9 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMwR4ESzHs9m+sH3b70y
|
||||
VUfMcW6/5CVDIquKLdeCobU2hopBVvu+3s46KmmxVh+wjYw7wElgjNp+1z8S+H4V
|
||||
MM7024UWdlzTPNJSgfjiIz94aDS74HkjR20uAs7Tn5NiVbUBS0HWCf4LwaBT4AbW
|
||||
WDv0mVTC9vHeVPdia1kSAtXtR7daCsCiaDqrUya7P0bjpSkP3buJMGPJtIz8NOcB
|
||||
QNWETFAu/MSpJQlWArn2HsCFE3SsQEytGSlgaDwiZ8Q4PIMIKZ1dcB0KxxnG2b4X
|
||||
FYNxlqQ3GHZ6IFeK5bLMLOe/rgIRkckAZJpoVW/s0/i0+1lwzweOjJx5ChSGWsRJ
|
||||
BwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
package de.nowchess.account.resource
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest
|
||||
import io.restassured.RestAssured
|
||||
import io.restassured.http.ContentType
|
||||
import org.hamcrest.Matchers.*
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
@QuarkusTest
|
||||
class AccountResourceTest:
|
||||
|
||||
private def givenRequest() = RestAssured.`given`().contentType(ContentType.JSON)
|
||||
|
||||
private def registerBody(username: String, email: String = "", password: String = "secret") =
|
||||
val resolvedEmail = if email.isEmpty then s"$username@example.com" else email
|
||||
s"""{"username":"$username","email":"$resolvedEmail","password":"$password"}"""
|
||||
|
||||
private def loginBody(username: String, password: String = "secret") =
|
||||
s"""{"username":"$username","password":"$password"}"""
|
||||
|
||||
private def registerAndLogin(username: String): String =
|
||||
givenRequest()
|
||||
.body(registerBody(username))
|
||||
.when()
|
||||
.post("/api/account")
|
||||
.`then`()
|
||||
.statusCode(200)
|
||||
givenRequest()
|
||||
.body(loginBody(username))
|
||||
.when()
|
||||
.post("/api/account/login")
|
||||
.`then`()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.path[String]("token")
|
||||
|
||||
@Test
|
||||
def registerReturns200(): Unit =
|
||||
givenRequest()
|
||||
.body(registerBody("alice"))
|
||||
.when()
|
||||
.post("/api/account")
|
||||
.`then`()
|
||||
.statusCode(200)
|
||||
.body("username", is("alice"))
|
||||
.body("rating", is(1500))
|
||||
|
||||
@Test
|
||||
def registerConflictOnDuplicateUsername(): Unit =
|
||||
givenRequest().body(registerBody("bob")).when().post("/api/account")
|
||||
givenRequest()
|
||||
.body(registerBody("bob"))
|
||||
.when()
|
||||
.post("/api/account")
|
||||
.`then`()
|
||||
.statusCode(409)
|
||||
.body("error", containsString("bob"))
|
||||
|
||||
@Test
|
||||
def loginReturns200WithToken(): Unit =
|
||||
givenRequest().body(registerBody("charlie")).when().post("/api/account")
|
||||
givenRequest()
|
||||
.body(loginBody("charlie"))
|
||||
.when()
|
||||
.post("/api/account/login")
|
||||
.`then`()
|
||||
.statusCode(200)
|
||||
.body("token", notNullValue())
|
||||
|
||||
@Test
|
||||
def loginUnauthorizedOnWrongPassword(): Unit =
|
||||
givenRequest().body(registerBody("dave")).when().post("/api/account")
|
||||
givenRequest()
|
||||
.body(loginBody("dave", "wrongpassword"))
|
||||
.when()
|
||||
.post("/api/account/login")
|
||||
.`then`()
|
||||
.statusCode(401)
|
||||
|
||||
@Test
|
||||
def getMeReturns200(): Unit =
|
||||
val token = registerAndLogin("eve")
|
||||
givenRequest()
|
||||
.header("Authorization", s"Bearer $token")
|
||||
.when()
|
||||
.get("/api/account/me")
|
||||
.`then`()
|
||||
.statusCode(200)
|
||||
.body("username", is("eve"))
|
||||
|
||||
@Test
|
||||
def getPublicProfileReturns200(): Unit =
|
||||
givenRequest().body(registerBody("frank")).when().post("/api/account")
|
||||
givenRequest()
|
||||
.when()
|
||||
.get("/api/account/frank")
|
||||
.`then`()
|
||||
.statusCode(200)
|
||||
.body("username", is("frank"))
|
||||
|
||||
@Test
|
||||
def getPublicProfileNotFound(): Unit =
|
||||
givenRequest()
|
||||
.when()
|
||||
.get("/api/account/doesnotexist")
|
||||
.`then`()
|
||||
.statusCode(404)
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
package de.nowchess.account.resource
|
||||
|
||||
import de.nowchess.account.client.{CoreGameClient, CoreGameResponse}
|
||||
import io.quarkus.test.InjectMock
|
||||
import io.quarkus.test.junit.QuarkusTest
|
||||
import io.restassured.RestAssured
|
||||
import io.restassured.http.ContentType
|
||||
import org.eclipse.microprofile.rest.client.inject.RestClient
|
||||
import org.hamcrest.Matchers.*
|
||||
import org.junit.jupiter.api.{BeforeEach, Test}
|
||||
import org.mockito.{ArgumentMatchers, Mockito}
|
||||
|
||||
@QuarkusTest
|
||||
class ChallengeResourceTest:
|
||||
|
||||
@InjectMock
|
||||
@RestClient
|
||||
// scalafix:off DisableSyntax.var
|
||||
var coreGameClient: CoreGameClient = scala.compiletime.uninitialized
|
||||
// scalafix:on
|
||||
|
||||
@BeforeEach
|
||||
def setup(): Unit =
|
||||
Mockito.when(coreGameClient.createGame(ArgumentMatchers.any())).thenReturn(CoreGameResponse("test-game-id"))
|
||||
|
||||
private def givenRequest() = RestAssured.`given`().contentType(ContentType.JSON)
|
||||
|
||||
private def registerBody(username: String, suffix: String = "") =
|
||||
val email = s"$username$suffix@test.com"
|
||||
s"""{"username":"$username$suffix","email":"$email","password":"secret"}"""
|
||||
|
||||
private def loginBody(username: String, suffix: String = "") =
|
||||
s"""{"username":"$username$suffix","password":"secret"}"""
|
||||
|
||||
private def registerAndLogin(username: String, suffix: String = ""): String =
|
||||
givenRequest().body(registerBody(username, suffix)).when().post("/api/account")
|
||||
givenRequest()
|
||||
.body(loginBody(username, suffix))
|
||||
.when()
|
||||
.post("/api/account/login")
|
||||
.`then`()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.path[String]("token")
|
||||
|
||||
private val clockBody =
|
||||
"""{"color":"random","timeControl":{"type":"clock","limit":300,"increment":5}}"""
|
||||
|
||||
private def authed(token: String) =
|
||||
givenRequest().header("Authorization", s"Bearer $token")
|
||||
|
||||
@Test
|
||||
def createChallengeReturns201(): Unit =
|
||||
val t1 = registerAndLogin("user1c")
|
||||
registerAndLogin("user2c")
|
||||
authed(t1)
|
||||
.contentType(ContentType.JSON)
|
||||
.body(clockBody)
|
||||
.when()
|
||||
.post("/api/challenge/user2c")
|
||||
.`then`()
|
||||
.statusCode(201)
|
||||
.body("status", is("created"))
|
||||
.body("color", is("random"))
|
||||
|
||||
@Test
|
||||
def createChallengeConflictOnDuplicate(): Unit =
|
||||
val t1 = registerAndLogin("user1dup")
|
||||
registerAndLogin("user2dup")
|
||||
authed(t1).contentType(ContentType.JSON).body(clockBody).when().post("/api/challenge/user2dup")
|
||||
authed(t1)
|
||||
.contentType(ContentType.JSON)
|
||||
.body(clockBody)
|
||||
.when()
|
||||
.post("/api/challenge/user2dup")
|
||||
.`then`()
|
||||
.statusCode(409)
|
||||
|
||||
@Test
|
||||
def createChallengeSelfForbidden(): Unit =
|
||||
val token = registerAndLogin("selfuser")
|
||||
authed(token)
|
||||
.contentType(ContentType.JSON)
|
||||
.body(clockBody)
|
||||
.when()
|
||||
.post("/api/challenge/selfuser")
|
||||
.`then`()
|
||||
.statusCode(400)
|
||||
|
||||
@Test
|
||||
def acceptChallengeReturns200(): Unit =
|
||||
val t1 = registerAndLogin("accUser1")
|
||||
val t2 = registerAndLogin("accUser2")
|
||||
val challengeId = authed(t1)
|
||||
.contentType(ContentType.JSON)
|
||||
.body(clockBody)
|
||||
.when()
|
||||
.post("/api/challenge/accUser2")
|
||||
.`then`()
|
||||
.statusCode(201)
|
||||
.extract()
|
||||
.path[String]("id")
|
||||
authed(t2)
|
||||
.when()
|
||||
.post(s"/api/challenge/$challengeId/accept")
|
||||
.`then`()
|
||||
.statusCode(200)
|
||||
.body("status", is("accepted"))
|
||||
.body("gameId", is("test-game-id"))
|
||||
|
||||
@Test
|
||||
def declineChallengeReturns200(): Unit =
|
||||
val t1 = registerAndLogin("decUser1")
|
||||
val t2 = registerAndLogin("decUser2")
|
||||
val challengeId = authed(t1)
|
||||
.contentType(ContentType.JSON)
|
||||
.body(clockBody)
|
||||
.when()
|
||||
.post("/api/challenge/decUser2")
|
||||
.`then`()
|
||||
.statusCode(201)
|
||||
.extract()
|
||||
.path[String]("id")
|
||||
authed(t2)
|
||||
.contentType(ContentType.JSON)
|
||||
.body("""{"reason":"later"}""")
|
||||
.when()
|
||||
.post(s"/api/challenge/$challengeId/decline")
|
||||
.`then`()
|
||||
.statusCode(200)
|
||||
.body("status", is("declined"))
|
||||
.body("declineReason", is("later"))
|
||||
|
||||
@Test
|
||||
def cancelChallengeReturns200(): Unit =
|
||||
val t1 = registerAndLogin("canUser1")
|
||||
registerAndLogin("canUser2")
|
||||
val challengeId = authed(t1)
|
||||
.contentType(ContentType.JSON)
|
||||
.body(clockBody)
|
||||
.when()
|
||||
.post("/api/challenge/canUser2")
|
||||
.`then`()
|
||||
.statusCode(201)
|
||||
.extract()
|
||||
.path[String]("id")
|
||||
authed(t1)
|
||||
.when()
|
||||
.post(s"/api/challenge/$challengeId/cancel")
|
||||
.`then`()
|
||||
.statusCode(200)
|
||||
.body("status", is("canceled"))
|
||||
|
||||
@Test
|
||||
def listChallengesReturnsInAndOut(): Unit =
|
||||
val t1 = registerAndLogin("listUser1")
|
||||
registerAndLogin("listUser2")
|
||||
registerAndLogin("listUser3")
|
||||
authed(t1)
|
||||
.contentType(ContentType.JSON)
|
||||
.body(clockBody)
|
||||
.when()
|
||||
.post("/api/challenge/listUser2")
|
||||
.`then`()
|
||||
.statusCode(201)
|
||||
authed(t1)
|
||||
.contentType(ContentType.JSON)
|
||||
.body(clockBody)
|
||||
.when()
|
||||
.post("/api/challenge/listUser3")
|
||||
.`then`()
|
||||
.statusCode(201)
|
||||
authed(t1)
|
||||
.when()
|
||||
.get("/api/challenge")
|
||||
.`then`()
|
||||
.statusCode(200)
|
||||
.body("out.size()", is(2))
|
||||
.body("in.size()", is(0))
|
||||
Reference in New Issue
Block a user