Refactoring Follows Tests

Add missing route GET /constitutions/{constitution}/follows
This commit is contained in:
2020-03-16 21:24:24 +01:00
parent 10b2844620
commit 0e912ef4b1
9 changed files with 121 additions and 66 deletions

View File

@@ -7,7 +7,7 @@
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" /> <option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
<option name="METHOD_NAME" value="" /> <option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="class" /> <option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags=&quot;@follow&quot; -Dstrict" /> <option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags=&quot;@follow&quot;" />
<option name="PARAMETERS" value="" /> <option name="PARAMETERS" value="" />
<option name="TEST_SEARCH_SCOPE"> <option name="TEST_SEARCH_SCOPE">
<value defaultName="wholeProject" /> <value defaultName="wholeProject" />

View File

@@ -34,9 +34,6 @@ object ConstitutionPaths {
@Location("/constitutions/{constitution}") @Location("/constitutions/{constitution}")
class ConstitutionRequest(val constitution: ConstitutionEntity) class ConstitutionRequest(val constitution: ConstitutionEntity)
@Location("/constitutions/{constitution}/follow")
class ConstitutionFollowRequest(val constitution: ConstitutionEntity)
@Location("/constitutions") @Location("/constitutions")
class PostConstitutionRequest class PostConstitutionRequest
} }

View File

@@ -15,7 +15,7 @@ import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepositor
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
object FollowConstitutionPaths { object FollowConstitutionPaths {
@Location("/constitutions/{constitution}/follow") @Location("/constitutions/{constitution}/follows")
class ConstitutionFollowRequest(val constitution: ConstitutionRef) class ConstitutionFollowRequest(val constitution: ConstitutionRef)
@Location("/citizens/{citizen}/follows/constitutions") @Location("/citizens/{citizen}/follows/constitutions")
@@ -38,6 +38,13 @@ fun Route.followConstitution(repo: FollowConstitutionRepository) {
call.respond(HttpStatusCode.NoContent) call.respond(HttpStatusCode.NoContent)
} }
get<FollowConstitutionPaths.ConstitutionFollowRequest> {
repo.findFollow(citizen, it.constitution)?.let { follow ->
assertCan(VIEW, follow)
call.respond(follow)
} ?: call.respond(HttpStatusCode.NotFound)
}
get<FollowConstitutionPaths.CitizenFollowConstitutionRequest> { get<FollowConstitutionPaths.CitizenFollowConstitutionRequest> {
val follows = repo.findByCitizen(it.citizen) val follows = repo.findByCitizen(it.citizen)
assertCan(VIEW, follows.result) assertCan(VIEW, follows.result)

View File

@@ -27,6 +27,10 @@ class ArticleSteps : En, KoinTest {
createArticle(extraData) createArticle(extraData)
} }
Given("I have article with ID {string}") { id: String ->
createArticle(id = UUID.fromString(id))
}
Given("I have comment created by {word} {word} on article {string}:") { firstName: String, lastName: String, articleId: String, extraData: DataTable? -> Given("I have comment created by {word} {word} on article {string}:") { firstName: String, lastName: String, articleId: String, extraData: DataTable? ->
commentArticle(articleId, firstName, lastName, extraData) commentArticle(articleId, firstName, lastName, extraData)
} }
@@ -35,17 +39,17 @@ class ArticleSteps : En, KoinTest {
} }
} }
private fun createArticle(extraData: DataTable? = null) { private fun createArticle(extraData: DataTable? = null, id: UUID? = null) {
val params = extraData?.asMap<String, String>(String::class.java, String::class.java) val params = extraData?.asMap<String, String>(String::class.java, String::class.java)
val createdByUsername = params?.get("createdBy") val createdByUsername = params?.get("createdBy")
val username = (createdByUsername ?: "username"+UUID.randomUUID().toString()) val username = (createdByUsername ?: "username" + UUID.randomUUID().toString())
.toLowerCase().replace(' ', '-') .toLowerCase().replace(' ', '-')
val createdBy = if (createdByUsername != null) { val createdBy = if (createdByUsername != null) {
get<CitizenRepository>().findByUsername(username) ?: error("Citizen not exist") get<CitizenRepository>().findByUsername(username) ?: error("Citizen not exist")
} else { } else {
val first = "firstName"+UUID.randomUUID().toString() val first = "firstName" + UUID.randomUUID().toString()
val last = "lastName"+UUID.randomUUID().toString() val last = "lastName" + UUID.randomUUID().toString()
Citizen( Citizen(
birthday = DateTime.now(), birthday = DateTime.now(),
name = CitizenI.Name( name = CitizenI.Name(
@@ -60,7 +64,7 @@ class ArticleSteps : En, KoinTest {
} }
val article = ArticleEntity( val article = ArticleEntity(
id = params?.get("id")?.toUUID() ?: UUID.randomUUID(), id = id ?: params?.get("id")?.toUUID() ?: UUID.randomUUID(),
title = "hello", title = "hello",
content = "bla bla bla", content = "bla bla bla",
description = "A super article", description = "A super article",
@@ -74,7 +78,9 @@ class ArticleSteps : En, KoinTest {
val article = get<ArticleRepository>().findById(UUID.fromString(articleId)) ?: error("Article not exist") val article = get<ArticleRepository>().findById(UUID.fromString(articleId)) ?: error("Article not exist")
val citizen = get<CitizenRepository>().findByUsername(("$firstName-$lastName".toLowerCase()).toLowerCase().replace(' ', '-')) ?: error("Citizen not exist") val citizen = get<CitizenRepository>().findByUsername(
("$firstName-$lastName".toLowerCase()).toLowerCase().replace(' ', '-')
) ?: error("Citizen not exist")
val comment: CommentEntity<ArticleRef> = CommentEntity( val comment: CommentEntity<ArticleRef> = CommentEntity(
id = params?.get("id")?.let { UUID.fromString(it) } ?: UUID.randomUUID(), id = params?.get("id")?.let { UUID.fromString(it) } ?: UUID.randomUUID(),

View File

@@ -9,11 +9,10 @@ import org.joda.time.DateTime
import org.koin.test.KoinTest import org.koin.test.KoinTest
import org.koin.test.get import org.koin.test.get
import java.util.* import java.util.*
import fr.dcproject.entity.Constitution as ConstitutionEntity
import fr.dcproject.entity.Comment as CommentEntity import fr.dcproject.entity.Comment as CommentEntity
import fr.dcproject.entity.User as UserEntity import fr.dcproject.entity.User as UserEntity
import fr.dcproject.repository.Constitution as ConstitutionRepository
import fr.dcproject.repository.Citizen as CitizenRepository import fr.dcproject.repository.Citizen as CitizenRepository
import fr.dcproject.repository.Constitution as ConstitutionRepository
class ConstitutionSteps : En, KoinTest { class ConstitutionSteps : En, KoinTest {
init { init {
@@ -27,6 +26,10 @@ class ConstitutionSteps : En, KoinTest {
createConstitution(extraData) createConstitution(extraData)
} }
Given("I have constitution with ID {string}") { id: String? ->
createConstitution(id = UUID.fromString(id))
}
Given("I have comment created by {word} {word} on constitution {string}:") { firstName: String, lastName: String, constitutionId: String, extraData: DataTable? -> Given("I have comment created by {word} {word} on constitution {string}:") { firstName: String, lastName: String, constitutionId: String, extraData: DataTable? ->
commentConstitution(constitutionId, firstName, lastName, extraData) commentConstitution(constitutionId, firstName, lastName, extraData)
} }
@@ -35,7 +38,7 @@ class ConstitutionSteps : En, KoinTest {
} }
} }
private fun createConstitution(extraData: DataTable? = null) { private fun createConstitution(extraData: DataTable? = null, id: UUID? = null) {
val params = extraData?.asMap<String, String>(String::class.java, String::class.java) val params = extraData?.asMap<String, String>(String::class.java, String::class.java)
val createdByUsername = params?.get("createdBy") val createdByUsername = params?.get("createdBy")
val username = (createdByUsername ?: "username"+UUID.randomUUID().toString()) val username = (createdByUsername ?: "username"+UUID.randomUUID().toString())
@@ -64,7 +67,7 @@ class ConstitutionSteps : En, KoinTest {
) )
val constitution = ConstitutionSimple<CitizenSimple, ConstitutionSimple.TitleSimple<ArticleRef>>( val constitution = ConstitutionSimple<CitizenSimple, ConstitutionSimple.TitleSimple<ArticleRef>>(
id = params?.get("id")?.toUUID() ?: UUID.randomUUID(), id = id ?: params?.get("id")?.toUUID() ?: UUID.randomUUID(),
title = "hello", title = "hello",
titles = mutableListOf(title1), titles = mutableListOf(title1),
anonymous = false, anonymous = false,

View File

@@ -1,6 +1,7 @@
package feature package feature
import fr.dcproject.entity.ArticleRef import fr.dcproject.entity.ArticleRef
import fr.dcproject.entity.ConstitutionRef
import fr.dcproject.entity.Follow import fr.dcproject.entity.Follow
import fr.dcproject.utils.toUUID import fr.dcproject.utils.toUUID
import io.cucumber.java8.En import io.cucumber.java8.En
@@ -8,14 +9,21 @@ import org.koin.test.KoinTest
import org.koin.test.get import org.koin.test.get
import fr.dcproject.repository.Citizen as CitizenRepository import fr.dcproject.repository.Citizen as CitizenRepository
import fr.dcproject.repository.FollowArticle as FollowArticleRepository import fr.dcproject.repository.FollowArticle as FollowArticleRepository
import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository
class FollowSteps : En, KoinTest { class FollowSteps : En, KoinTest {
init { init {
Given("The citizen {word} {word} follow article {string}") { firstName: String, lastName: String, articleId: String -> Given("I have follow of {word} {word} on article {string}") { firstName: String, lastName: String, articleId: String ->
val username = "$firstName-$lastName".toLowerCase() val username = "$firstName-$lastName".toLowerCase()
val citizen = get<CitizenRepository>().findByUsername(username) ?: error("Citizen not exist") val citizen = get<CitizenRepository>().findByUsername(username) ?: error("Citizen not exist")
val follow = Follow(createdBy = citizen, target = ArticleRef(articleId.toUUID())) val follow = Follow(createdBy = citizen, target = ArticleRef(articleId.toUUID()))
get<FollowArticleRepository>().follow(follow) get<FollowArticleRepository>().follow(follow)
} }
Given("I have follow of {word} {word} on constitution {string}") { firstName: String, lastName: String, constitutionId: String ->
val username = "$firstName-$lastName".toLowerCase()
val citizen = get<CitizenRepository>().findByUsername(username) ?: error("Citizen not exist")
val follow = Follow(createdBy = citizen, target = ConstitutionRef(constitutionId.toUUID()))
get<FollowConstitutionRepository>().follow(follow)
}
} }
} }

View File

@@ -1,50 +0,0 @@
@follow
Feature: follow Article and Constitution
# Article
Scenario: The route for follow article must response a 201 and return object
Given I am authenticated as John Doe with id "64b7b379-2298-43ec-b428-ba134930cabd"
When I send a POST request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b/follows"
Then the response status code should be 201
Scenario: The route for get follows of articles must response a 200 and return objects
Given I have citizen John Smith with id "e3c0b08c-11be-418e-95e0-8596b4402feb"
When I send a GET request to "/citizens/e3c0b08c-11be-418e-95e0-8596b4402feb/follows/articles"
Then the response status code should be 200
And the response should contain object:
| current_page | 1 |
| limit | 50 |
Scenario: The route for unfollow article must response a 204
Given I am authenticated as John Doe with id "64b7b379-2298-43ec-b428-ba134930cabd"
When I send a DELETE request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b/follows"
Then the response status code should be 204
# Constitution
Scenario: The route for follow constitution must response a 201 and return object
Given I am authenticated as John Doe with id "64b7b379-2298-43ec-b428-ba134930cabd"
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
Given I have citizen John Smith with id "e3c0b08c-11be-418e-95e0-8596b4402feb"
When I send a GET request to "/citizens/e3c0b08c-11be-418e-95e0-8596b4402feb/follows/constitutions"
Then the response status code should be 200
And the response should contain object:
| current_page | 1 |
| limit | 50 |
Scenario: The route for unfollow constitution must response a 204
Given I am authenticated as John Doe with id "64b7b379-2298-43ec-b428-ba134930cabd"
When I send a DELETE request to "/constitutions/72aa1ee1-4963-eb44-c9e0-5ce6e0f18f00/follow"
Then the response status code should be 204
Scenario: I can know if I follow an article
Given I have article with id "3ee4e6d0-f312-4940-872d-1f578c8d824c"
And I have citizen Marie Curie
And I am authenticated as Marie Curie
And The citizen Marie Curie follow article "3ee4e6d0-f312-4940-872d-1f578c8d824c"
When I send a GET request to "/articles/3ee4e6d0-f312-4940-872d-1f578c8d824c/follows"
Then the response status code should be 200
And the JSON should contain:
| target.id | 3ee4e6d0-f312-4940-872d-1f578c8d824c |

View File

@@ -0,0 +1,42 @@
@follow
Feature: follow Article
# Article
Scenario: The route for follow article must response a 201 and return
Given I have citizen Louis Pasteur
And I am authenticated as Louis Pasteur
And I have article
| id | 04754b7b-edef-4adc-af81-75e3aadeebea |
When I send a POST request to "/articles/04754b7b-edef-4adc-af81-75e3aadeebea/follows"
Then the response status code should be 201
Scenario: The route for get follows of articles must response a 200 and return objects
Given I have citizen Johannes Kepler with ID "e4592d53-3660-4264-8353-ebdbf5d9c41c"
And I am authenticated as Johannes Kepler
And I have article
| id | d743619a-1f6b-4d20-a2d6-8e81f0e6a4c8 |
And I have follow of Johannes Kepler on article "d743619a-1f6b-4d20-a2d6-8e81f0e6a4c8"
When I send a GET request to "/citizens/e4592d53-3660-4264-8353-ebdbf5d9c41c/follows/articles"
Then the response status code should be 200
And the response should contain object:
| current_page | 1 |
| limit | 50 |
Scenario: The route for unfollow article must response a 204
Given I have citizen Thomas Edison
And I am authenticated as Thomas Edison
And I have article
| id | aad3aa9d-95fd-4919-9e84-46255f620e31 |
And I have follow of Thomas Edison on article "aad3aa9d-95fd-4919-9e84-46255f620e31"
When I send a DELETE request to "/articles/aad3aa9d-95fd-4919-9e84-46255f620e31/follows"
Then the response status code should be 204
Scenario: I can know if I follow an article
Given I have article with ID "3ee4e6d0-f312-4940-872d-1f578c8d824c"
And I have citizen Marie Curie
And I am authenticated as Marie Curie
And I have follow of Marie Curie on article "3ee4e6d0-f312-4940-872d-1f578c8d824c"
When I send a GET request to "/articles/3ee4e6d0-f312-4940-872d-1f578c8d824c/follows"
Then the response status code should be 200
And the JSON should contain:
| target.id | 3ee4e6d0-f312-4940-872d-1f578c8d824c |

View File

@@ -0,0 +1,42 @@
@follow
Feature: follow Constitution
# Constitution
Scenario: The route for follow constitution must response a 201 and return
Given I have citizen Dmitri Mendeleïev
And I am authenticated as Dmitri Mendeleïev
And I have constitution
| id | f6553f5e-0cf5-476a-b84e-15e52ec9d8f9 |
When I send a POST request to "/constitutions/f6553f5e-0cf5-476a-b84e-15e52ec9d8f9/follows"
Then the response status code should be 201
Scenario: The route for get follows of constitutions must response a 200 and return objects
Given I have citizen André-Marie Ampère with ID "877b45b0-302d-487d-8944-6d03ccdbd0f8"
And I am authenticated as André-Marie Ampère
And I have constitution
| id | 7f642078-8e74-47fc-9712-0c37531674a0 |
And I have follow of André-Marie Ampère on constitution "7f642078-8e74-47fc-9712-0c37531674a0"
When I send a GET request to "/citizens/877b45b0-302d-487d-8944-6d03ccdbd0f8/follows/constitutions"
Then the response status code should be 200
And the response should contain object:
| current_page | 1 |
| limit | 50 |
Scenario: The route for unfollow constitution must response a 204
Given I have citizen Claude Ptolémée
And I am authenticated as Claude Ptolémée
And I have constitution
| id | 4ea03776-a28c-4202-9b90-db1b942946c1 |
And I have follow of Claude Ptolémée on constitution "4ea03776-a28c-4202-9b90-db1b942946c1"
When I send a DELETE request to "/constitutions/4ea03776-a28c-4202-9b90-db1b942946c1/follows"
Then the response status code should be 204
Scenario: I can know if I follow an constitution
Given I have constitution with ID "5141e781-ebcd-4de0-8c2b-7d23d4cd58b5"
And I have citizen Denis Papin
And I am authenticated as Denis Papin
And I have follow of Denis Papin on constitution "5141e781-ebcd-4de0-8c2b-7d23d4cd58b5"
When I send a GET request to "/constitutions/5141e781-ebcd-4de0-8c2b-7d23d4cd58b5/follows"
Then the response status code should be 200
And the JSON should contain:
| target.id | 5141e781-ebcd-4de0-8c2b-7d23d4cd58b5 |