Big refactoring #77
@@ -30,7 +30,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: docker/postgresql
|
context: docker/postgresql
|
||||||
ports:
|
ports:
|
||||||
- 5433:5432
|
- 15432:5432
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_PASSWORD: ${DB_NAME}
|
POSTGRES_PASSWORD: ${DB_NAME}
|
||||||
POSTGRES_USER: ${DB_USER}
|
POSTGRES_USER: ${DB_USER}
|
||||||
|
|||||||
10
src/main/kotlin/fr/dcproject/common/BitMaskEnum.kt
Normal file
10
src/main/kotlin/fr/dcproject/common/BitMaskEnum.kt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package fr.dcproject.common
|
||||||
|
|
||||||
|
interface BitMaskI {
|
||||||
|
val bit: Long
|
||||||
|
|
||||||
|
infix operator fun contains(which: BitMaskI): Boolean = bit and which.bit == which.bit
|
||||||
|
infix operator fun plus(mask: BitMaskI): BitMaskI = BitMask(mask.bit and this.bit)
|
||||||
|
}
|
||||||
|
|
||||||
|
class BitMask(override val bit: Long) : BitMaskI
|
||||||
@@ -11,10 +11,12 @@ import fr.dcproject.component.citizen.database.CitizenI
|
|||||||
import fr.dcproject.component.citizen.database.CitizenRepository
|
import fr.dcproject.component.citizen.database.CitizenRepository
|
||||||
import io.ktor.application.call
|
import io.ktor.application.call
|
||||||
import io.ktor.features.BadRequestException
|
import io.ktor.features.BadRequestException
|
||||||
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.http.HttpStatusCode
|
||||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||||
import io.ktor.locations.Location
|
import io.ktor.locations.Location
|
||||||
import io.ktor.locations.post
|
import io.ktor.locations.post
|
||||||
|
import io.ktor.request.accept
|
||||||
import io.ktor.response.respond
|
import io.ktor.response.respond
|
||||||
import io.ktor.response.respondText
|
import io.ktor.response.respondText
|
||||||
import io.ktor.routing.Route
|
import io.ktor.routing.Route
|
||||||
@@ -61,8 +63,17 @@ object Register {
|
|||||||
post<RegisterRequest> {
|
post<RegisterRequest> {
|
||||||
try {
|
try {
|
||||||
val citizen = call.receiveOrBadRequest<Input>().toCitizen()
|
val citizen = call.receiveOrBadRequest<Input>().toCitizen()
|
||||||
val createdCitizen = citizenRepo.insertWithUser(citizen)?.user ?: throw BadRequestException("Bad request")
|
citizenRepo.insertWithUser(citizen)?.user?.makeToken()?.let { token ->
|
||||||
call.respondText(createdCitizen.makeToken())
|
if (call.request.accept() == ContentType.Application.Json.toString()) {
|
||||||
|
call.respond(
|
||||||
|
object {
|
||||||
|
val token: String = token
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
call.respondText(token)
|
||||||
|
}
|
||||||
|
} ?: throw BadRequestException("Bad request")
|
||||||
} catch (e: MissingKotlinParameterException) {
|
} catch (e: MissingKotlinParameterException) {
|
||||||
call.respond(HttpStatusCode.BadRequest)
|
call.respond(HttpStatusCode.BadRequest)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,6 +256,82 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example:
|
example:
|
||||||
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBdXRoZW50aWNhdGlvbiIsImlzcyI6ImRjLXByb2plY3QuZnIiLCJpZCI6ImQ1NDRhNmE4LWJhYjgtNDU2MC05NWIxLThhZjAyMDNkOTEwNCIsImV4cCI6MTU2NzA3Mzc0Mn0.0VTetv8fZFjVgpJ-bwJpidGNHJUOmgj8vuZcZXzwnLa7TtFwcXWvh3bDPYHqB66nmOfXyM57XnHDbmRwtipCag'
|
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBdXRoZW50aWNhdGlvbiIsImlzcyI6ImRjLXByb2plY3QuZnIiLCJpZCI6ImQ1NDRhNmE4LWJhYjgtNDU2MC05NWIxLThhZjAyMDNkOTEwNCIsImV4cCI6MTU2NzA3Mzc0Mn0.0VTetv8fZFjVgpJ-bwJpidGNHJUOmgj8vuZcZXzwnLa7TtFwcXWvh3bDPYHqB66nmOfXyM57XnHDbmRwtipCag'
|
||||||
|
/register:
|
||||||
|
post:
|
||||||
|
summary: Create account
|
||||||
|
tags:
|
||||||
|
- authentification
|
||||||
|
operationId: register
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- birthday
|
||||||
|
- email
|
||||||
|
- user
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- firstName
|
||||||
|
- lastName
|
||||||
|
properties:
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
example:
|
||||||
|
john
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
example:
|
||||||
|
Doe
|
||||||
|
birthday:
|
||||||
|
type: string
|
||||||
|
format: 'date'
|
||||||
|
example: '1984-12-25'
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
format: email
|
||||||
|
example: my.email@dc-project.fr
|
||||||
|
user:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- username
|
||||||
|
- password
|
||||||
|
properties:
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
example:
|
||||||
|
john-doe
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
example:
|
||||||
|
azerty
|
||||||
|
format: password
|
||||||
|
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: User created and JWT returned
|
||||||
|
content:
|
||||||
|
text/plain:
|
||||||
|
example:
|
||||||
|
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBdXRoZW50aWNhdGlvbiIsImlzcyI6ImRjLXByb2plY3QuZnIiLCJpZCI6ImQ1NDRhNmE4LWJhYjgtNDU2MC05NWIxLThhZjAyMDNkOTEwNCIsImV4cCI6MTU2NzA3Mzc0Mn0.0VTetv8fZFjVgpJ-bwJpidGNHJUOmgj8vuZcZXzwnLa7TtFwcXWvh3bDPYHqB66nmOfXyM57XnHDbmRwtipCag'
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
token:
|
||||||
|
type: string
|
||||||
|
example:
|
||||||
|
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBdXRoZW50aWNhdGlvbiIsImlzcyI6ImRjLXByb2plY3QuZnIiLCJpZCI6ImQ1NDRhNmE4LWJhYjgtNDU2MC05NWIxLThhZjAyMDNkOTEwNCIsImV4cCI6MTU2NzA3Mzc0Mn0.0VTetv8fZFjVgpJ-bwJpidGNHJUOmgj8vuZcZXzwnLa7TtFwcXWvh3bDPYHqB66nmOfXyM57XnHDbmRwtipCag'
|
||||||
|
400:
|
||||||
|
description: Bad request
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
description: sdf
|
||||||
|
|
||||||
components:
|
components:
|
||||||
parameters:
|
parameters:
|
||||||
page:
|
page:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package integration
|
package integration
|
||||||
|
|
||||||
|
import integration.steps.`when`.Validate
|
||||||
import integration.steps.then.`And have property`
|
import integration.steps.then.`And have property`
|
||||||
import integration.steps.then.`And the response should not be null`
|
import integration.steps.then.`And the response should not be null`
|
||||||
import integration.steps.then.`Then the response should be`
|
import integration.steps.then.`Then the response should be`
|
||||||
@@ -67,8 +68,8 @@ class `Citizen routes` : BaseTest() {
|
|||||||
`authenticated as`("Georges", "Charpak")
|
`authenticated as`("Georges", "Charpak")
|
||||||
`with body`("""
|
`with body`("""
|
||||||
{
|
{
|
||||||
"old_password": "azerty",
|
"oldPassword": "azerty",
|
||||||
"new_password": "qwerty"
|
"newPassword": "qwerty"
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
} `Then the response should be` Created
|
} `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`() {
|
fun `I cannot change my password if request is bad formated`() {
|
||||||
withIntegrationApplication {
|
withIntegrationApplication {
|
||||||
`Given I have citizen`("Louis", "Breguet", id = "6cf2a19d-d15d-4ee5-b2a9-907afd26b525")
|
`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")
|
`authenticated as`("Louis", "Breguet")
|
||||||
`with body`("""
|
`with body`("""
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -84,9 +84,9 @@ class `Comment articles routes` : BaseTest() {
|
|||||||
`When I send a GET request`("/citizens/292a20cc-4a60-489e-9866-a95d38ffaf47/comments/articles") {
|
`When I send a GET request`("/citizens/292a20cc-4a60-489e-9866-a95d38ffaf47/comments/articles") {
|
||||||
} `Then the response should be` OK and {
|
} `Then the response should be` OK and {
|
||||||
`And the response should not be null`()
|
`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`("$.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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import integration.steps.given.`Given I have constitution`
|
|||||||
import integration.steps.given.`authenticated as`
|
import integration.steps.given.`authenticated as`
|
||||||
import io.ktor.http.HttpStatusCode.Companion.Created
|
import io.ktor.http.HttpStatusCode.Companion.Created
|
||||||
import io.ktor.http.HttpStatusCode.Companion.OK
|
import io.ktor.http.HttpStatusCode.Companion.OK
|
||||||
import io.ktor.server.testing.setBody
|
|
||||||
import org.junit.jupiter.api.Tag
|
import org.junit.jupiter.api.Tag
|
||||||
import org.junit.jupiter.api.Tags
|
import org.junit.jupiter.api.Tags
|
||||||
import org.junit.jupiter.api.Test
|
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") {
|
`When I send a GET request`("/citizens/46e0bda9-ca6a-4c65-a58b-7e7267a0bbc5/comments/constitutions") {
|
||||||
} `Then the response should be` OK and {
|
} `Then the response should be` OK and {
|
||||||
`And the response should not be null`()
|
`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`("$.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`("$.result[0].target.id", "34ddd50a-da00-4a90-a869-08baa2a121be")
|
||||||
`And the response should contain list`("$.result[*]", 1, 1)
|
`And the response should contain list`("$.result[*]", 1, 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class `Follow articles routes` : BaseTest() {
|
|||||||
`authenticated as`("Johannes", "Kepler")
|
`authenticated as`("Johannes", "Kepler")
|
||||||
} `Then the response should be` OK and {
|
} `Then the response should be` OK and {
|
||||||
`And the response should not be null`()
|
`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`("$.limit", 50)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class `Follow constitutions routes` : BaseTest() {
|
|||||||
`authenticated as`("André-Marie", "Ampère")
|
`authenticated as`("André-Marie", "Ampère")
|
||||||
} `Then the response should be` OK and {
|
} `Then the response should be` OK and {
|
||||||
`And the response should not be null`()
|
`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`("$.limit", 50)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
package integration
|
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`.`When I send a POST request`
|
||||||
import integration.steps.`when`.`with body`
|
import integration.steps.`when`.`with body`
|
||||||
import io.ktor.http.HttpStatusCode
|
import integration.steps.then.`And the response should be null`
|
||||||
import org.amshove.kluent.`should be null`
|
import integration.steps.then.`And the response should contain pattern`
|
||||||
import org.amshove.kluent.`should contain`
|
import integration.steps.then.`And the response should not be null`
|
||||||
import org.amshove.kluent.`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.Tag
|
||||||
import org.junit.jupiter.api.Tags
|
import org.junit.jupiter.api.Tags
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
@@ -21,7 +24,7 @@ class `Register routes` : BaseTest() {
|
|||||||
`When I send a POST request`("/register") {
|
`When I send a POST request`("/register") {
|
||||||
`with body`("""
|
`with body`("""
|
||||||
{
|
{
|
||||||
"name": {"first_name":"George", "last_name":"MICHEL"},
|
"name": {"firstName":"George", "lastName":"MICHEL"},
|
||||||
"birthday": "2001-01-01",
|
"birthday": "2001-01-01",
|
||||||
"user":{
|
"user":{
|
||||||
"username": "george-junior",
|
"username": "george-junior",
|
||||||
@@ -30,10 +33,9 @@ class `Register routes` : BaseTest() {
|
|||||||
"email": "george-junior@gmail.com"
|
"email": "george-junior@gmail.com"
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
}.`Then the response should be`(HttpStatusCode.OK) {
|
} `Then the response should be` OK and {
|
||||||
content
|
`And the response should not be null`()
|
||||||
.`should not be null`()
|
`And the response should contain pattern`("$.token", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.")
|
||||||
.`should contain`("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,19 +43,19 @@ class `Register routes` : BaseTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `I cannot register if no username was sent`() {
|
fun `I cannot register if no username was sent`() {
|
||||||
withIntegrationApplication {
|
withIntegrationApplication {
|
||||||
`When I send a POST request`("/register") {
|
`When I send a POST request`("/register", Validate.RESPONSE_BODY) {
|
||||||
`with body`("""
|
`with body`("""
|
||||||
{
|
{
|
||||||
"name": {"first_name":"George2", "last_name":"MICHEL2"},
|
"name": {"firstName":"George2", "lastName":"MICHEL2"},
|
||||||
"birthday": "2001-01-01",
|
"birthday": "2001-01-01",
|
||||||
"user":{
|
"user":{
|
||||||
"username": "",
|
|
||||||
"password": ""
|
"password": ""
|
||||||
}
|
},
|
||||||
|
"email": "george-junior@gmail.com"
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
}.`Then the response should be`(HttpStatusCode.BadRequest) {
|
} `Then the response should be` BadRequest and {
|
||||||
content.`should be null`()
|
`And the response should be null`()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class `Vote routes` : BaseTest() {
|
|||||||
`When I send a GET request`("/citizens/c044823d-e778-4256-9016-b1334bf933d3/votes/articles") {
|
`When I send a GET request`("/citizens/c044823d-e778-4256-9016-b1334bf933d3/votes/articles") {
|
||||||
`authenticated as`("Carl", "Gauss")
|
`authenticated as`("Carl", "Gauss")
|
||||||
} `Then the response should be` OK and {
|
} `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`("$.limit", 50)
|
||||||
`And the response should contain`("$.total", 1)
|
`And the response should contain`("$.total", 1)
|
||||||
`And the response should contain`("$.result[0].note", 1)
|
`And the response should contain`("$.result[0].note", 1)
|
||||||
|
|||||||
@@ -50,11 +50,11 @@ class `Workgroup routes` : BaseTest() {
|
|||||||
`And the response should contain`("$.id", "ab469134-bf14-4856-b093-ae1aa990f977")
|
`And the response should contain`("$.id", "ab469134-bf14-4856-b093-ae1aa990f977")
|
||||||
`And the response should contain`("$.name", "Les Mousquets")
|
`And the response should contain`("$.name", "Les Mousquets")
|
||||||
`And the response should contain`(
|
`And the response should contain`(
|
||||||
"$.members[*].citizen.name[?(@.first_name=='Stephen')].first_name",
|
"$.members[*].citizen.name[?(@.firstName=='Stephen')].firstName",
|
||||||
"Stephen"
|
"Stephen"
|
||||||
)
|
)
|
||||||
`And the response should contain`(
|
`And the response should contain`(
|
||||||
"$.members[*].citizen.name[?(@.first_name=='Sadi')].first_name",
|
"$.members[*].citizen.name[?(@.firstName=='Sadi')].firstName",
|
||||||
"Sadi"
|
"Sadi"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
fun TestApplicationResponse.`And the schema response body must be valid`(contentType: ContentType? = ContentType.Application.Json) {
|
||||||
operation(route) { api, uri ->
|
operation { api, uri ->
|
||||||
/* Validate Response */
|
/* Validate Response */
|
||||||
this.apply {
|
this.apply {
|
||||||
val status = call.response.status()
|
val status = call.response.status()
|
||||||
|
val responseContent: JsonNode = if (content != null)
|
||||||
|
ObjectMapper().readTree(content)
|
||||||
|
else TextNode("")
|
||||||
|
|
||||||
getResponse(status?.value?.toString() ?: error("HttpStatus not found"))
|
getResponse(status?.value?.toString() ?: error("HttpStatus not found"))
|
||||||
?.getContentMediaType(contentType.toString())
|
?.getContentMediaType(contentType.toString())
|
||||||
?.schema
|
?.schema
|
||||||
?.validate(api, ObjectMapper().readTree(content))
|
?.validate(api, responseContent)
|
||||||
?: fail("""No Status "${status.value}" found with media type "$contentType" for "$this $uri".""")
|
?: 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 */
|
/* Validate Request URL */
|
||||||
this.apply {
|
this.apply {
|
||||||
Url(call.request.uri).parameters.forEach { parameter: String, values: List<String> ->
|
Url(call.request.uri).parameters.forEach { parameter: String, values: List<String> ->
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package integration.steps.`when`
|
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 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.application.ApplicationCall
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.http.HttpHeaders
|
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.TestApplicationRequest
|
||||||
import io.ktor.server.testing.setBody
|
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) {
|
return handleRequest(true) {
|
||||||
method = HttpMethod.Get
|
method = HttpMethod.Get
|
||||||
if (uri != null) {
|
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())
|
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
|
||||||
setup?.let { it() }
|
setup?.let { it() }
|
||||||
}.apply {
|
}.valid(validate)
|
||||||
if (validate) {
|
|
||||||
response.`And the schema must be valid`()
|
|
||||||
requestBody?.let { body ->
|
|
||||||
response.`And the schema request body must be valid`(body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
return handleRequest(true) {
|
||||||
method = HttpMethod.Post
|
method = HttpMethod.Post
|
||||||
if (uri != null) {
|
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.ContentType, ContentType.Application.Json.toString())
|
||||||
addHeader(HttpHeaders.Accept, ContentType.Application.Json.toString())
|
addHeader(HttpHeaders.Accept, ContentType.Application.Json.toString())
|
||||||
setup?.let { it() }
|
setup?.let { it() }
|
||||||
}.apply {
|
}.valid(validate)
|
||||||
if (validate) {
|
|
||||||
response.`And the schema must be valid`()
|
|
||||||
requestBody?.let { body ->
|
|
||||||
response.`And the schema request body must be valid`(body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
return handleRequest(true) {
|
||||||
method = HttpMethod.Put
|
method = HttpMethod.Put
|
||||||
if (uri != null) {
|
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())
|
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
|
||||||
setup?.let { it() }
|
setup?.let { it() }
|
||||||
}.apply {
|
}.valid(validate)
|
||||||
if (validate) {
|
|
||||||
response.`And the schema must be valid`()
|
|
||||||
requestBody?.let { body ->
|
|
||||||
response.`And the schema request body must be valid`(body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
return handleRequest(true) {
|
||||||
method = HttpMethod.Delete
|
method = HttpMethod.Delete
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
@@ -76,14 +81,7 @@ fun TestApplicationEngine.`When I send a DELETE request`(uri: String? = null, va
|
|||||||
setup?.let { it() }?.let {
|
setup?.let { it() }?.let {
|
||||||
setBody(it.trimIndent())
|
setBody(it.trimIndent())
|
||||||
}
|
}
|
||||||
}.apply {
|
}.valid(validate)
|
||||||
if (validate) {
|
|
||||||
response.`And the schema must be valid`()
|
|
||||||
requestBody?.let { body ->
|
|
||||||
response.`And the schema request body must be valid`(body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val requestBodies: MutableMap<ApplicationCall, String> = mutableMapOf()
|
private val requestBodies: MutableMap<ApplicationCall, String> = mutableMapOf()
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ db {
|
|||||||
database = test
|
database = test
|
||||||
username = test
|
username = test
|
||||||
password = test
|
password = test
|
||||||
port = 5433
|
port = 15432
|
||||||
}
|
}
|
||||||
|
|
||||||
redis {
|
redis {
|
||||||
|
|||||||
Reference in New Issue
Block a user