Test openapi schema of Register

Fix some routes
Improve Schema Validation
This commit is contained in:
2021-03-16 00:53:10 +01:00
parent 235de4e5ff
commit 0cf1aea9bf
15 changed files with 179 additions and 73 deletions

View File

@@ -1,5 +1,6 @@
package integration
import integration.steps.`when`.Validate
import integration.steps.then.`And have property`
import integration.steps.then.`And the response should not be null`
import integration.steps.then.`Then the response should be`
@@ -67,8 +68,8 @@ class `Citizen routes` : BaseTest() {
`authenticated as`("Georges", "Charpak")
`with body`("""
{
"old_password": "azerty",
"new_password": "qwerty"
"oldPassword": "azerty",
"newPassword": "qwerty"
}
""")
} `Then the response should be` Created
@@ -79,7 +80,7 @@ class `Citizen routes` : BaseTest() {
fun `I cannot change my password if request is bad formated`() {
withIntegrationApplication {
`Given I have citizen`("Louis", "Breguet", id = "6cf2a19d-d15d-4ee5-b2a9-907afd26b525")
`When I send a PUT request`("/citizens/6cf2a19d-d15d-4ee5-b2a9-907afd26b525/password/change") {
`When I send a PUT request`("/citizens/6cf2a19d-d15d-4ee5-b2a9-907afd26b525/password/change", Validate.RESPONSE_BODY) {
`authenticated as`("Louis", "Breguet")
`with body`("""
{

View File

@@ -84,9 +84,9 @@ class `Comment articles routes` : BaseTest() {
`When I send a GET request`("/citizens/292a20cc-4a60-489e-9866-a95d38ffaf47/comments/articles") {
} `Then the response should be` OK and {
`And the response should not be null`()
`And the response should contain`("$.current_page", 1)
`And the response should contain`("$.currentPage", 1)
`And the response should contain`("$.limit", 50)
`And the response should contain`("$.result[0]created_by.id", "292a20cc-4a60-489e-9866-a95d38ffaf47")
`And the response should contain`("$.result[0]createdBy.id", "292a20cc-4a60-489e-9866-a95d38ffaf47")
}
}
}

View File

@@ -15,7 +15,6 @@ import integration.steps.given.`Given I have constitution`
import integration.steps.given.`authenticated as`
import io.ktor.http.HttpStatusCode.Companion.Created
import io.ktor.http.HttpStatusCode.Companion.OK
import io.ktor.server.testing.setBody
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Tags
import org.junit.jupiter.api.Test
@@ -51,9 +50,9 @@ class `Comment constitutions routes` : BaseTest() {
`When I send a GET request`("/citizens/46e0bda9-ca6a-4c65-a58b-7e7267a0bbc5/comments/constitutions") {
} `Then the response should be` OK and {
`And the response should not be null`()
`And the response should contain`("$.current_page", 1)
`And the response should contain`("$.currentPage", 1)
`And the response should contain`("$.limit", 50)
`And the response should contain`("$.result[0].created_by.id", "46e0bda9-ca6a-4c65-a58b-7e7267a0bbc5")
`And the response should contain`("$.result[0].createdBy.id", "46e0bda9-ca6a-4c65-a58b-7e7267a0bbc5")
`And the response should contain`("$.result[0].target.id", "34ddd50a-da00-4a90-a869-08baa2a121be")
`And the response should contain list`("$.result[*]", 1, 1)
}

View File

@@ -47,7 +47,7 @@ class `Follow articles routes` : BaseTest() {
`authenticated as`("Johannes", "Kepler")
} `Then the response should be` OK and {
`And the response should not be null`()
`And the response should contain`("$.current_page", 1)
`And the response should contain`("$.currentPage", 1)
`And the response should contain`("$.limit", 50)
}
}

View File

@@ -47,7 +47,7 @@ class `Follow constitutions routes` : BaseTest() {
`authenticated as`("André-Marie", "Ampère")
} `Then the response should be` OK and {
`And the response should not be null`()
`And the response should contain`("$.current_page", 1)
`And the response should contain`("$.currentPage", 1)
`And the response should contain`("$.limit", 50)
}
}

View File

@@ -1,12 +1,15 @@
package integration
import integration.steps.then.`Then the response should be`
import integration.steps.`when`.Validate
import integration.steps.`when`.`When I send a POST request`
import integration.steps.`when`.`with body`
import io.ktor.http.HttpStatusCode
import org.amshove.kluent.`should be null`
import org.amshove.kluent.`should contain`
import org.amshove.kluent.`should not be null`
import integration.steps.then.`And the response should be null`
import integration.steps.then.`And the response should contain pattern`
import integration.steps.then.`And the response should not be null`
import integration.steps.then.`Then the response should be`
import integration.steps.then.and
import io.ktor.http.HttpStatusCode.Companion.BadRequest
import io.ktor.http.HttpStatusCode.Companion.OK
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Tags
import org.junit.jupiter.api.Test
@@ -21,7 +24,7 @@ class `Register routes` : BaseTest() {
`When I send a POST request`("/register") {
`with body`("""
{
"name": {"first_name":"George", "last_name":"MICHEL"},
"name": {"firstName":"George", "lastName":"MICHEL"},
"birthday": "2001-01-01",
"user":{
"username": "george-junior",
@@ -30,10 +33,9 @@ class `Register routes` : BaseTest() {
"email": "george-junior@gmail.com"
}
""")
}.`Then the response should be`(HttpStatusCode.OK) {
content
.`should not be null`()
.`should contain`("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.")
} `Then the response should be` OK and {
`And the response should not be null`()
`And the response should contain pattern`("$.token", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.")
}
}
}
@@ -41,19 +43,19 @@ class `Register routes` : BaseTest() {
@Test
fun `I cannot register if no username was sent`() {
withIntegrationApplication {
`When I send a POST request`("/register") {
`When I send a POST request`("/register", Validate.RESPONSE_BODY) {
`with body`("""
{
"name": {"first_name":"George2", "last_name":"MICHEL2"},
"name": {"firstName":"George2", "lastName":"MICHEL2"},
"birthday": "2001-01-01",
"user":{
"username": "",
"password": ""
}
},
"email": "george-junior@gmail.com"
}
""")
}.`Then the response should be`(HttpStatusCode.BadRequest) {
content.`should be null`()
} `Then the response should be` BadRequest and {
`And the response should be null`()
}
}
}

View File

@@ -65,7 +65,7 @@ class `Vote routes` : BaseTest() {
`When I send a GET request`("/citizens/c044823d-e778-4256-9016-b1334bf933d3/votes/articles") {
`authenticated as`("Carl", "Gauss")
} `Then the response should be` OK and {
`And the response should contain`("$.current_page", 1)
`And the response should contain`("$.currentPage", 1)
`And the response should contain`("$.limit", 50)
`And the response should contain`("$.total", 1)
`And the response should contain`("$.result[0].note", 1)

View File

@@ -50,11 +50,11 @@ class `Workgroup routes` : BaseTest() {
`And the response should contain`("$.id", "ab469134-bf14-4856-b093-ae1aa990f977")
`And the response should contain`("$.name", "Les Mousquets")
`And the response should contain`(
"$.members[*].citizen.name[?(@.first_name=='Stephen')].first_name",
"$.members[*].citizen.name[?(@.firstName=='Stephen')].firstName",
"Stephen"
)
`And the response should contain`(
"$.members[*].citizen.name[?(@.first_name=='Sadi')].first_name",
"$.members[*].citizen.name[?(@.firstName=='Sadi')].firstName",
"Sadi"
)
}

View File

@@ -50,17 +50,26 @@ fun TestApplicationResponse.operation(route: String? = null, callback: Operation
}
}
fun TestApplicationResponse.`And the schema must be valid`(route: String? = null, contentType: ContentType? = ContentType.Application.Json) {
operation(route) { api, uri ->
fun TestApplicationResponse.`And the schema response body must be valid`(contentType: ContentType? = ContentType.Application.Json) {
operation { api, uri ->
/* Validate Response */
this.apply {
val status = call.response.status()
val responseContent: JsonNode = if (content != null)
ObjectMapper().readTree(content)
else TextNode("")
getResponse(status?.value?.toString() ?: error("HttpStatus not found"))
?.getContentMediaType(contentType.toString())
?.schema
?.validate(api, ObjectMapper().readTree(content))
?.validate(api, responseContent)
?: fail("""No Status "${status.value}" found with media type "$contentType" for "$this $uri".""")
}
}
}
fun TestApplicationResponse.`And the schema parameters must be valid`() {
operation { api, uri ->
/* Validate Request URL */
this.apply {
Url(call.request.uri).parameters.forEach { parameter: String, values: List<String> ->

View File

@@ -1,7 +1,9 @@
package integration.steps.`when`
import integration.steps.then.`And the schema must be valid`
import fr.dcproject.common.BitMaskI
import integration.steps.then.`And the schema parameters must be valid`
import integration.steps.then.`And the schema request body must be valid`
import integration.steps.then.`And the schema response body must be valid`
import io.ktor.application.ApplicationCall
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
@@ -11,7 +13,31 @@ import io.ktor.server.testing.TestApplicationEngine
import io.ktor.server.testing.TestApplicationRequest
import io.ktor.server.testing.setBody
fun TestApplicationEngine.`When I send a GET request`(uri: String? = null, validate: Boolean = true, setup: (TestApplicationRequest.() -> Unit)? = null): TestApplicationCall {
enum class Validate(override val bit: Long) : BitMaskI {
REQUEST_BODY(1),
REQUEST_PARAM(2),
REQUEST(3),
RESPONSE_BODY(4),
ALL(7);
}
fun TestApplicationCall.valid(validate: Validate): TestApplicationCall {
if (Validate.RESPONSE_BODY in validate) {
response.`And the schema response body must be valid`()
}
if (Validate.REQUEST_PARAM in validate) {
response.`And the schema parameters must be valid`()
}
if (Validate.REQUEST_BODY in validate) {
requestBody?.let { body ->
response.`And the schema request body must be valid`(body)
}
}
return this
}
fun TestApplicationEngine.`When I send a GET request`(uri: String? = null, validate: Validate = Validate.ALL, setup: (TestApplicationRequest.() -> Unit)? = null): TestApplicationCall {
return handleRequest(true) {
method = HttpMethod.Get
if (uri != null) {
@@ -19,17 +45,10 @@ fun TestApplicationEngine.`When I send a GET request`(uri: String? = null, valid
}
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
setup?.let { it() }
}.apply {
if (validate) {
response.`And the schema must be valid`()
requestBody?.let { body ->
response.`And the schema request body must be valid`(body)
}
}
}
}.valid(validate)
}
fun TestApplicationEngine.`When I send a POST request`(uri: String? = null, validate: Boolean = true, setup: (TestApplicationRequest.() -> Unit)? = null): TestApplicationCall {
fun TestApplicationEngine.`When I send a POST request`(uri: String? = null, validate: Validate = Validate.ALL, setup: (TestApplicationRequest.() -> Unit)? = null): TestApplicationCall {
return handleRequest(true) {
method = HttpMethod.Post
if (uri != null) {
@@ -38,17 +57,10 @@ fun TestApplicationEngine.`When I send a POST request`(uri: String? = null, vali
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
addHeader(HttpHeaders.Accept, ContentType.Application.Json.toString())
setup?.let { it() }
}.apply {
if (validate) {
response.`And the schema must be valid`()
requestBody?.let { body ->
response.`And the schema request body must be valid`(body)
}
}
}
}.valid(validate)
}
fun TestApplicationEngine.`When I send a PUT request`(uri: String? = null, validate: Boolean = true, setup: (TestApplicationRequest.() -> Unit)? = null): TestApplicationCall {
fun TestApplicationEngine.`When I send a PUT request`(uri: String? = null, validate: Validate = Validate.ALL, setup: (TestApplicationRequest.() -> Unit)? = null): TestApplicationCall {
return handleRequest(true) {
method = HttpMethod.Put
if (uri != null) {
@@ -56,17 +68,10 @@ fun TestApplicationEngine.`When I send a PUT request`(uri: String? = null, valid
}
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
setup?.let { it() }
}.apply {
if (validate) {
response.`And the schema must be valid`()
requestBody?.let { body ->
response.`And the schema request body must be valid`(body)
}
}
}
}.valid(validate)
}
fun TestApplicationEngine.`When I send a DELETE request`(uri: String? = null, validate: Boolean = true, setup: (TestApplicationRequest.() -> String?)? = null): TestApplicationCall {
fun TestApplicationEngine.`When I send a DELETE request`(uri: String? = null, validate: Validate = Validate.ALL, setup: (TestApplicationRequest.() -> String?)? = null): TestApplicationCall {
return handleRequest(true) {
method = HttpMethod.Delete
if (uri != null) {
@@ -76,14 +81,7 @@ fun TestApplicationEngine.`When I send a DELETE request`(uri: String? = null, va
setup?.let { it() }?.let {
setBody(it.trimIndent())
}
}.apply {
if (validate) {
response.`And the schema must be valid`()
requestBody?.let { body ->
response.`And the schema request body must be valid`(body)
}
}
}
}.valid(validate)
}
private val requestBodies: MutableMap<ApplicationCall, String> = mutableMapOf()