Refactoring of cucumber implementation
This commit is contained in:
@@ -1,25 +1,21 @@
|
||||
import cucumber.api.CucumberOptions
|
||||
import cucumber.api.Scenario
|
||||
import cucumber.api.java8.En
|
||||
import cucumber.api.junit.Cucumber
|
||||
import feature.Context
|
||||
import feature.KtorServerContext
|
||||
import fr.dcproject.config
|
||||
import fr.dcproject.module
|
||||
import fr.dcproject.utils.LoggerDelegate
|
||||
import fr.postgresjson.connexion.Connection
|
||||
import fr.postgresjson.connexion.Requester
|
||||
import fr.postgresjson.migration.Migrations
|
||||
import io.cucumber.core.api.Scenario
|
||||
import io.cucumber.java8.En
|
||||
import io.cucumber.junit.Cucumber
|
||||
import io.cucumber.junit.CucumberOptions
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.server.testing.TestApplicationEngine
|
||||
import io.ktor.server.testing.createTestEnvironment
|
||||
import io.ktor.server.testing.withTestApplication
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import org.junit.runner.RunWith
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.get
|
||||
import org.slf4j.Logger
|
||||
import java.util.concurrent.TimeUnit
|
||||
import feature.Context.Companion.current as contextCurrent
|
||||
|
||||
var unitialized: Boolean = false
|
||||
|
||||
@@ -29,6 +25,11 @@ var unitialized: Boolean = false
|
||||
@CucumberOptions(plugin = ["pretty"])
|
||||
class RunCucumberTest: En, KoinTest {
|
||||
private val logger: Logger? by LoggerDelegate()
|
||||
|
||||
val ktorContext = KtorServerContext {
|
||||
module()
|
||||
}
|
||||
|
||||
init {
|
||||
Before(-2) { _: Scenario ->
|
||||
if (!unitialized) {
|
||||
@@ -48,11 +49,11 @@ class RunCucumberTest: En, KoinTest {
|
||||
config.database = "test"
|
||||
config.username = "test"
|
||||
config.password = "test"
|
||||
contextCurrent = Context(TestApplicationEngine(createTestEnvironment()) {}, scenario)
|
||||
ktorContext.start()
|
||||
}
|
||||
|
||||
After { _: Scenario ->
|
||||
contextCurrent.engine.stop(0L, 0L, TimeUnit.MILLISECONDS)
|
||||
ktorContext.stop()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package feature
|
||||
|
||||
import cucumber.api.Scenario
|
||||
import fr.dcproject.module
|
||||
import io.ktor.application.Application
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.server.testing.TestApplicationCall
|
||||
import io.ktor.server.testing.TestApplicationEngine
|
||||
import io.ktor.server.testing.TestApplicationRequest
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@KtorExperimentalAPI
|
||||
class Context(
|
||||
val engine: TestApplicationEngine,
|
||||
val scenario: Scenario
|
||||
) {
|
||||
companion object {
|
||||
lateinit var current: Context
|
||||
}
|
||||
|
||||
init {
|
||||
engine.start()
|
||||
val moduleFunction: Application.() -> Unit = { module() }
|
||||
val test: TestApplicationEngine.() -> Unit = {
|
||||
moduleFunction(application)
|
||||
}
|
||||
engine.test()
|
||||
}
|
||||
|
||||
var call: TestApplicationCall? = null
|
||||
|
||||
private val requestContextConfigurations: MutableList<TestApplicationRequest.() -> Unit> = mutableListOf()
|
||||
fun setupRequest(testApplicationRequest: TestApplicationRequest) {
|
||||
requestContextConfigurations.forEach {
|
||||
it(testApplicationRequest)
|
||||
}
|
||||
}
|
||||
fun setupNextRequests(requestContextConfiguration: TestApplicationRequest.() -> Unit) = requestContextConfigurations.add(requestContextConfiguration)
|
||||
}
|
||||
|
||||
fun TestApplicationRequest.applyConfigurations() {
|
||||
Context.current.setupRequest(this)
|
||||
}
|
||||
56
src/test/kotlin/feature/KtorServerAuthSteps.kt
Normal file
56
src/test/kotlin/feature/KtorServerAuthSteps.kt
Normal file
@@ -0,0 +1,56 @@
|
||||
package feature
|
||||
|
||||
import com.auth0.jwt.JWT
|
||||
import com.auth0.jwt.algorithms.Algorithm
|
||||
import fr.dcproject.JwtConfig
|
||||
import fr.dcproject.entity.Citizen
|
||||
import fr.dcproject.entity.User
|
||||
import fr.postgresjson.connexion.Requester
|
||||
import io.cucumber.datatable.DataTable
|
||||
import io.cucumber.java8.En
|
||||
import io.ktor.http.HttpHeaders
|
||||
import org.joda.time.DateTime
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.get
|
||||
import org.koin.test.inject
|
||||
import java.util.*
|
||||
import kotlin.random.Random
|
||||
import fr.dcproject.repository.User as UserRepository
|
||||
|
||||
class KtorServerAuthSteps: En, KoinTest {
|
||||
private val requester: Requester by inject()
|
||||
init {
|
||||
When("I have citizen:") { body: DataTable ->
|
||||
val user = User(username = "jaque_${Random.nextInt(0, 10000)}", plainPassword = "azerty")
|
||||
requester
|
||||
.getFunction("insert_user")
|
||||
.selectOne(user)
|
||||
|
||||
val data = body.asMap<String, String>(String::class.java, String::class.java)
|
||||
val citizen = Citizen(
|
||||
id = UUID.fromString(data["id"]),
|
||||
name = Citizen.Name(data["firstName"], data["lastName"]),
|
||||
birthday = DateTime.now(),
|
||||
user = user
|
||||
)
|
||||
requester
|
||||
.getFunction("upsert_citizen")
|
||||
.selectOne(citizen)
|
||||
}
|
||||
|
||||
Given("I am authenticated as an user") {
|
||||
val id = UUID.randomUUID()
|
||||
val jwtAsString: String = JWT.create()
|
||||
.withIssuer("dc-project.fr")
|
||||
.withClaim("id", id.toString())
|
||||
.sign(Algorithm.HMAC512(JwtConfig.secret))
|
||||
|
||||
val user = User(id = id, username = "user", plainPassword = "azerty")
|
||||
get<UserRepository>().insert(user)
|
||||
|
||||
KtorServerContext.defaultServer.addPreRequestSetup {
|
||||
addHeader(HttpHeaders.Authorization, "Bearer $jwtAsString")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
54
src/test/kotlin/feature/KtorServerContext.kt
Normal file
54
src/test/kotlin/feature/KtorServerContext.kt
Normal file
@@ -0,0 +1,54 @@
|
||||
package feature
|
||||
|
||||
import io.ktor.application.Application
|
||||
import io.ktor.server.testing.TestApplicationCall
|
||||
import io.ktor.server.testing.TestApplicationEngine
|
||||
import io.ktor.server.testing.TestApplicationRequest
|
||||
import io.ktor.server.testing.createTestEnvironment
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.test.fail
|
||||
|
||||
class KtorServerContext(useByDefault: Boolean = true, val module: Application.() -> Unit) {
|
||||
|
||||
init { if (useByDefault) setDefault() }
|
||||
|
||||
companion object {
|
||||
lateinit var defaultServer: KtorServerContext
|
||||
}
|
||||
|
||||
private val engine = TestApplicationEngine(createTestEnvironment())
|
||||
|
||||
private data class RequestSetup(val setup: TestApplicationRequest.() -> Unit, val keepSetup: Boolean = true)
|
||||
private val preRequestSetup = mutableListOf<RequestSetup>()
|
||||
|
||||
var call: TestApplicationCall? = null
|
||||
|
||||
fun addPreRequestSetup(keepSetup: Boolean = true, hook: TestApplicationRequest.() -> Unit) {
|
||||
preRequestSetup.add(RequestSetup(hook, keepSetup))
|
||||
}
|
||||
|
||||
fun handleRequest(setup: TestApplicationRequest.() -> Unit) =
|
||||
try {
|
||||
call = engine.handleRequest {
|
||||
preRequestSetup.forEach { it.setup(this) }
|
||||
setup(this)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
fail("Request fail, $e")
|
||||
} finally {
|
||||
preRequestSetup.removeAll { !it.keepSetup }
|
||||
}
|
||||
|
||||
fun setDefault() {
|
||||
defaultServer = this
|
||||
}
|
||||
|
||||
fun start() {
|
||||
engine.start()
|
||||
module(engine.application)
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
engine.stop(0L, 0L, TimeUnit.MILLISECONDS)
|
||||
}
|
||||
}
|
||||
64
src/test/kotlin/feature/KtorServerRequestSteps.kt
Normal file
64
src/test/kotlin/feature/KtorServerRequestSteps.kt
Normal file
@@ -0,0 +1,64 @@
|
||||
package feature
|
||||
|
||||
import com.google.gson.JsonParser
|
||||
import io.cucumber.datatable.DataTable
|
||||
import io.cucumber.java8.En
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.HttpHeaders
|
||||
import io.ktor.http.HttpMethod
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.testing.setBody
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import kotlinx.serialization.ImplicitReflectionSerializer
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.opentest4j.AssertionFailedError
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@ImplicitReflectionSerializer
|
||||
@KtorExperimentalAPI
|
||||
class KtorServerRequestSteps : En {
|
||||
init {
|
||||
Given("Next request as headers:") { dataTable: DataTable ->
|
||||
KtorServerContext.defaultServer.addPreRequestSetup(false) {
|
||||
dataTable.asMap<String, String>(String::class.java, String::class.java).forEach { key, value ->
|
||||
this.addHeader(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Given("I send a {word} request to {string} with body:") { method: String, uri: String, body: String ->
|
||||
KtorServerContext.defaultServer.handleRequest {
|
||||
this.method = HttpMethod.parse(method)
|
||||
this.uri = uri
|
||||
this.addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
|
||||
setBody(body)
|
||||
}
|
||||
}
|
||||
|
||||
Given("I send a {word} request to {string}") { method: String, uri: String ->
|
||||
KtorServerContext.defaultServer.handleRequest {
|
||||
this.method = HttpMethod.parse(method.toUpperCase())
|
||||
this.uri = uri
|
||||
}
|
||||
}
|
||||
|
||||
Then("the response status code should be {int}") { statusCode: Int ->
|
||||
assertEquals(HttpStatusCode.fromValue(statusCode), KtorServerContext.defaultServer.call?.response?.status())
|
||||
}
|
||||
|
||||
Then("the response should contain object:") { expected: DataTable ->
|
||||
val call = KtorServerContext.defaultServer.call ?: throw AssertionFailedError("No call")
|
||||
val response = JsonParser().parse(call.response.content).getAsJsonObject()
|
||||
|
||||
expected.asMap<String, String>(String::class.java, String::class.java).forEach { (key, valueExpected) ->
|
||||
assertTrue(response.has(key))
|
||||
Assertions.assertEquals(valueExpected, response.get(key).asString)
|
||||
}
|
||||
}
|
||||
|
||||
Then("print last response") {
|
||||
print(KtorServerContext.defaultServer.call?.response?.content)
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/test/kotlin/feature/KtorServerRestSteps.kt
Normal file
55
src/test/kotlin/feature/KtorServerRestSteps.kt
Normal file
@@ -0,0 +1,55 @@
|
||||
package feature
|
||||
|
||||
import io.cucumber.datatable.DataTable
|
||||
import io.cucumber.java8.En
|
||||
import kotlinx.serialization.ImplicitReflectionSerializer
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonArray
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import kotlinx.serialization.parse
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.fail
|
||||
|
||||
@ImplicitReflectionSerializer
|
||||
class KtorServerRestSteps : En {
|
||||
init {
|
||||
Then("the JSON should contain:") { dataTable: DataTable ->
|
||||
dataTable.asMap<String, String>(String::class.java, String::class.java).forEach { (key, value) ->
|
||||
val jsonPrimitive = findJsonElement(key) as? JsonPrimitive ?: fail("\"$key\" element isn't json primitive")
|
||||
assertEquals(jsonPrimitive.content, value)
|
||||
}
|
||||
}
|
||||
|
||||
Then("the JSON element {word} should have {int} item(s)") { node: String, count: Int ->
|
||||
val jsonArray = findJsonElement(node) as? JsonArray ?: fail("\"$node\" element isn't json array")
|
||||
assertEquals(count, jsonArray.size)
|
||||
}
|
||||
|
||||
Then("the JSON should have {int} item(s)") { count: Int ->
|
||||
val jsonArray = responseJsonElement as? JsonArray ?: fail("The json response isn't array")
|
||||
assertEquals(count, jsonArray.size)
|
||||
}
|
||||
}
|
||||
|
||||
private fun findJsonElement(node: String): JsonElement {
|
||||
var jsonElement: JsonElement = responseJsonElement
|
||||
val elements = node.split(".")
|
||||
|
||||
elements.forEach {
|
||||
val asArrayIndex = """\d+""".toRegex().find(it)
|
||||
|
||||
jsonElement = if (asArrayIndex != null) {
|
||||
val index = asArrayIndex.groups.first()!!
|
||||
jsonElement.jsonArray.get(index.value.toInt())
|
||||
} else {
|
||||
jsonElement.jsonObject.get(it) ?: throw AssertionError("\"$node\" element not found on json response")
|
||||
}
|
||||
}
|
||||
|
||||
return jsonElement
|
||||
}
|
||||
|
||||
private val responseJsonElement: JsonElement
|
||||
get() = Json.parse(KtorServerContext.defaultServer.call?.response?.content ?: fail("The response isn't valid JSON"))
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
package feature
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonParser
|
||||
import cucumber.api.java8.En
|
||||
import fr.dcproject.entity.Citizen
|
||||
import fr.dcproject.entity.User
|
||||
import fr.postgresjson.connexion.Requester
|
||||
import fr.postgresjson.migration.Migrations
|
||||
import io.cucumber.datatable.DataTable
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.HttpHeaders
|
||||
import io.ktor.http.HttpMethod
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.testing.TestApplicationCall
|
||||
import io.ktor.server.testing.TestApplicationEngine
|
||||
import io.ktor.server.testing.setBody
|
||||
import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.inject
|
||||
import org.opentest4j.AssertionFailedError
|
||||
import java.util.*
|
||||
import kotlin.random.Random
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.asserter
|
||||
import feature.Context.Companion.current as currentContext
|
||||
|
||||
class Request: En, KoinTest {
|
||||
private val migrations: Migrations by inject()
|
||||
private val requester: Requester by inject()
|
||||
init {
|
||||
When("I have citizen:") { body: DataTable ->
|
||||
val user = User(username = "jaque_${Random.nextInt(0, 10000)}", plainPassword = "azerty")
|
||||
val test: TestApplicationEngine.() -> Unit = {
|
||||
requester
|
||||
.getFunction("insert_user")
|
||||
.selectOne(user)
|
||||
|
||||
val data = body.asMap<String, String>(String::class.java, String::class.java)
|
||||
val citizen = Citizen(
|
||||
id = UUID.fromString(data["id"]),
|
||||
name = Citizen.Name(data["firstName"], data["lastName"]),
|
||||
birthday = DateTime.now(),
|
||||
user = user
|
||||
)
|
||||
requester
|
||||
.getFunction("upsert_citizen")
|
||||
.selectOne(citizen)
|
||||
}
|
||||
|
||||
currentContext.engine.test()
|
||||
}
|
||||
|
||||
When("I send a {string} request to {string} with body:") { method: String, uri: String, body: String ->
|
||||
val test: TestApplicationEngine.() -> Unit = {
|
||||
currentContext.call = handleRequest {
|
||||
applyConfigurations()
|
||||
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
|
||||
this.method = HttpMethod.parse(method)
|
||||
this.uri = uri
|
||||
setBody(body)
|
||||
}
|
||||
}
|
||||
|
||||
currentContext.engine.test()
|
||||
}
|
||||
|
||||
When("I send a {string} request to {string}") { method: String, uri: String ->
|
||||
val test: TestApplicationEngine.() -> Unit = {
|
||||
currentContext.call = handleRequest {
|
||||
applyConfigurations()
|
||||
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
|
||||
this.method = HttpMethod.parse(method.toUpperCase())
|
||||
this.uri = uri
|
||||
}
|
||||
}
|
||||
|
||||
currentContext.engine.test()
|
||||
}
|
||||
|
||||
Then("the response status code should be {int}") { statusCode: Int ->
|
||||
val call: TestApplicationCall = currentContext.call ?: throw AssertionFailedError("No call", statusCode, null)
|
||||
with(call) {
|
||||
assertEquals(HttpStatusCode.fromValue(statusCode), response.status(), response.content)
|
||||
}
|
||||
}
|
||||
|
||||
And("the response should contain:") { expected: DataTable ->
|
||||
val call: TestApplicationCall = currentContext.call ?: throw AssertionFailedError("No call")
|
||||
val p = call.response
|
||||
val response = Gson().fromJson<List<Map<String, String>>>(p.content, List::class.java)
|
||||
|
||||
expected.asMap<String, String>(String::class.java, String::class.java).forEach { (key, value) ->
|
||||
response.forEach {
|
||||
if (it.containsKey(key)) {
|
||||
assertEquals(it[key], value)
|
||||
return@And
|
||||
}
|
||||
}
|
||||
asserter.fail("The response not contain $key field")
|
||||
}
|
||||
}
|
||||
|
||||
And("the response should contain object:") { expected: DataTable ->
|
||||
val call: TestApplicationCall = currentContext.call ?: throw AssertionFailedError("No call")
|
||||
val p = call.response
|
||||
val response = JsonParser().parse(p.content).getAsJsonObject()
|
||||
|
||||
expected.asMap<String, String>(String::class.java, String::class.java).forEach { (key, valueExpected) ->
|
||||
assertTrue(response.has(key))
|
||||
assertEquals(valueExpected, response.get(key).asString)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
Feature: articles routes
|
||||
|
||||
Scenario: The route for get articles must response a 200
|
||||
When I send a "GET" request to "/articles"
|
||||
When I send a GET request to "/articles"
|
||||
Then the response status code should be 200
|
||||
|
||||
Scenario: The route for get one article must response a 200 and return article
|
||||
When I send a "GET" request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b"
|
||||
When I send a GET request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b"
|
||||
Then the response status code should be 200
|
||||
And the response should contain object:
|
||||
| id | 9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b |
|
||||
@@ -15,7 +15,8 @@ Feature: articles routes
|
||||
| id | 64b7b379-2298-43ec-b428-ba134930cabd |
|
||||
| firstName | Jaque |
|
||||
| lastName | Dupuis |
|
||||
When I send a "POST" request to "/articles" with body:
|
||||
And I am authenticated as an user
|
||||
When I send a POST request to "/articles" with body:
|
||||
"""
|
||||
{
|
||||
"version_id": "09c418b6-63ba-448b-b38b-502b41cd500e",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Feature: citizens routes
|
||||
|
||||
Scenario: The route for get citizens must response a 200
|
||||
When I send a "GET" request to "/citizens"
|
||||
When I send a GET request to "/citizens"
|
||||
Then the response status code should be 200
|
||||
|
||||
Scenario: The route for get one citizen must response a 200 and return citizen
|
||||
When I send a "GET" request to "/citizens/6434f4f9-f570-f22a-c134-8668350651ff"
|
||||
When I send a GET request to "/citizens/6434f4f9-f570-f22a-c134-8668350651ff"
|
||||
Then the response status code should be 200
|
||||
And the response should contain object:
|
||||
| id | 6434f4f9-f570-f22a-c134-8668350651ff |
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Feature: constitution routes
|
||||
|
||||
Scenario: The route for get constitutions must response a 200
|
||||
When I send a "GET" request to "/constitutions"
|
||||
When I send a GET request to "/constitutions"
|
||||
Then the response status code should be 200
|
||||
|
||||
Scenario: The route for get one constitution must response a 200 and return constitution
|
||||
When I send a "GET" request to "/constitutions/0ca489a6-ef68-8bd5-2355-5793d4b3d66c"
|
||||
When I send a GET request to "/constitutions/0ca489a6-ef68-8bd5-2355-5793d4b3d66c"
|
||||
Then the response status code should be 200
|
||||
And the response should contain object:
|
||||
| id | 0ca489a6-ef68-8bd5-2355-5793d4b3d66c |
|
||||
@@ -15,7 +15,7 @@ Feature: constitution routes
|
||||
| id | 64b7b379-2298-43ec-b428-ba134930cabd |
|
||||
| firstName | Jaque |
|
||||
| lastName | Dupuis |
|
||||
When I send a "POST" request to "/constitutions" with body:
|
||||
When I send a POST request to "/constitutions" with body:
|
||||
"""
|
||||
{
|
||||
"version_id":"15814bb6-8d90-4c6a-a456-c3939a8ec75e",
|
||||
|
||||
@@ -6,7 +6,7 @@ Feature: follow Article and Constitution
|
||||
| id | 64b7b379-2298-43ec-b428-ba134930cabd |
|
||||
| firstName | Jaque |
|
||||
| lastName | Dupuis |
|
||||
When I send a "POST" request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b/follow"
|
||||
When I send a POST request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b/follow"
|
||||
Then the response status code should be 201
|
||||
|
||||
Scenario: The route for get follows of articles must response a 200 and return objects
|
||||
@@ -14,7 +14,7 @@ Feature: follow Article and Constitution
|
||||
| id | 64b7b379-2298-43ec-b428-ba134930cabd |
|
||||
| firstName | Jaque |
|
||||
| lastName | Dupuis |
|
||||
When I send a "GET" request to "/citizens/64b7b379-2298-43ec-b428-ba134930cabd/follows/articles"
|
||||
When I send a GET request to "/citizens/64b7b379-2298-43ec-b428-ba134930cabd/follows/articles"
|
||||
Then the response status code should be 200
|
||||
And the response should contain object:
|
||||
| current_page | 1 |
|
||||
@@ -25,7 +25,7 @@ Feature: follow Article and Constitution
|
||||
| id | 64b7b379-2298-43ec-b428-ba134930cabd |
|
||||
| firstName | Jaque |
|
||||
| lastName | Dupuis |
|
||||
When I send a "DELETE" request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b/follow"
|
||||
When I send a DELETE request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b/follow"
|
||||
Then the response status code should be 204
|
||||
|
||||
# Constitution
|
||||
@@ -34,7 +34,7 @@ Feature: follow Article and Constitution
|
||||
| id | 64b7b379-2298-43ec-b428-ba134930cabd |
|
||||
| firstName | Jaque |
|
||||
| lastName | Dupuis |
|
||||
When I send a "POST" request to "/constitutions/72aa1ee1-4963-eb44-c9e0-5ce6e0f18f00/follow"
|
||||
When I send a POST request to "/constitutions/72aa1ee1-4963-eb44-c9e0-5ce6e0f18f00/follow"
|
||||
Then the response status code should be 201
|
||||
|
||||
Scenario: The route for get follows of constitutions must response a 200 and return objects
|
||||
@@ -42,7 +42,7 @@ Feature: follow Article and Constitution
|
||||
| id | 64b7b379-2298-43ec-b428-ba134930cabd |
|
||||
| firstName | Jaque |
|
||||
| lastName | Dupuis |
|
||||
When I send a "GET" request to "/citizens/64b7b379-2298-43ec-b428-ba134930cabd/follows/constitutions"
|
||||
When I send a GET request to "/citizens/64b7b379-2298-43ec-b428-ba134930cabd/follows/constitutions"
|
||||
Then the response status code should be 200
|
||||
And the response should contain object:
|
||||
| current_page | 1 |
|
||||
@@ -53,5 +53,5 @@ Feature: follow Article and Constitution
|
||||
| id | 64b7b379-2298-43ec-b428-ba134930cabd |
|
||||
| firstName | Jaque |
|
||||
| lastName | Dupuis |
|
||||
When I send a "DELETE" request to "/constitutions/72aa1ee1-4963-eb44-c9e0-5ce6e0f18f00/follow"
|
||||
When I send a DELETE request to "/constitutions/72aa1ee1-4963-eb44-c9e0-5ce6e0f18f00/follow"
|
||||
Then the response status code should be 204
|
||||
|
||||
Reference in New Issue
Block a user