diff --git a/src/main/kotlin/fr/dcproject/component/citizen/Citizen.kt b/src/main/kotlin/fr/dcproject/component/citizen/Citizen.kt index b8f497f..c407922 100644 --- a/src/main/kotlin/fr/dcproject/component/citizen/Citizen.kt +++ b/src/main/kotlin/fr/dcproject/component/citizen/Citizen.kt @@ -10,6 +10,7 @@ import fr.postgresjson.entity.EntityCreatedAt import fr.postgresjson.entity.EntityCreatedAtImp import fr.postgresjson.entity.EntityDeletedAt import fr.postgresjson.entity.EntityDeletedAtImp +import fr.postgresjson.entity.Serializable import fr.postgresjson.entity.UuidEntity import fr.postgresjson.entity.UuidEntityI import org.joda.time.DateTime @@ -101,7 +102,7 @@ interface CitizenI : UuidEntityI { override val civility: String? = null ) : NameI - interface NameI { + interface NameI : Serializable { val firstName: String val lastName: String val civility: String? diff --git a/src/main/kotlin/fr/dcproject/component/citizen/CitizenRepository.kt b/src/main/kotlin/fr/dcproject/component/citizen/CitizenRepository.kt index 1b9ca97..f710b00 100644 --- a/src/main/kotlin/fr/dcproject/component/citizen/CitizenRepository.kt +++ b/src/main/kotlin/fr/dcproject/component/citizen/CitizenRepository.kt @@ -1,6 +1,7 @@ package fr.dcproject.component.citizen import fr.dcproject.component.auth.UserI +import fr.dcproject.component.citizen.CitizenI.Name import fr.postgresjson.connexion.Paginated import fr.postgresjson.connexion.Requester import fr.postgresjson.repository.RepositoryI @@ -16,9 +17,13 @@ class CitizenRepository(override var requester: Requester) : RepositoryI { .getFunction("find_citizen_by_user_id") .selectOne("user_id" to user.id) - fun findByUsername(unsername: String): Citizen? = requester + fun findByUsername(username: String): Citizen? = requester .getFunction("find_citizen_by_username") - .selectOne("username" to unsername) + .selectOne("username" to username) + + fun findByName(name: Name): Citizen? = requester + .getFunction("find_citizen_by_name") + .selectOne("name" to name) fun findByEmail(email: String): Citizen? = requester .getFunction("find_citizen_by_email") diff --git a/src/test/kotlin/integration/Follow constitutions routes.kt b/src/test/kotlin/integration/Follow constitutions routes.kt index 6da9063..015bac0 100644 --- a/src/test/kotlin/integration/Follow constitutions routes.kt +++ b/src/test/kotlin/integration/Follow constitutions routes.kt @@ -8,9 +8,7 @@ import integration.steps.`when`.`When I send a DELETE request` import integration.steps.`when`.`When I send a GET request` import integration.steps.`when`.`When I send a POST request` import integration.steps.and -import integration.steps.given.`And follow article` import integration.steps.given.`And follow constitution` -import integration.steps.given.`Given I have article` import integration.steps.given.`Given I have citizen` import integration.steps.given.`Given I have constitution` import integration.steps.given.`authenticated as` @@ -24,7 +22,7 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance @TestInstance(TestInstance.Lifecycle.PER_CLASS) -@Tags(Tag("integration"), Tag("article"), Tag("follow")) +@Tags(Tag("integration"), Tag("constitution"), Tag("follow")) class `Follow constitutions routes` : BaseTest() { @Test fun `I can follow constitution`() { diff --git a/src/test/kotlin/integration/Opinion routes.kt b/src/test/kotlin/integration/Opinion routes.kt new file mode 100644 index 0000000..3b7114a --- /dev/null +++ b/src/test/kotlin/integration/Opinion routes.kt @@ -0,0 +1,138 @@ +package integration + +import fr.dcproject.component.citizen.CitizenI.Name +import integration.steps.`And the response should contain list` +import integration.steps.`And the response should contain` +import integration.steps.`Then the response should be` +import integration.steps.`when`.`When I send a GET request` +import integration.steps.`when`.`When I send a PUT request` +import integration.steps.and +import integration.steps.given.`Given I have an opinion choice` +import integration.steps.given.`Given I have article` +import integration.steps.given.`Given I have citizen` +import integration.steps.given.`Given I have opinion on article` +import integration.steps.given.`authenticated as` +import io.ktor.http.HttpStatusCode.Companion.Created +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 +import org.junit.jupiter.api.TestInstance + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Tags(Tag("integration"), Tag("article"), Tag("opinion")) +class `Opinion routes` : BaseTest() { + @Test + fun `I can get all opinion choices`() { + withIntegrationApplication { + `Given I have an opinion choice`("Opinion1") + `Given I have an opinion choice`("Opinion2") + `When I send a GET request`("/opinions") { + } `Then the response should be` OK and { + `And the response should contain`("$.[0]name", "Opinion1") + `And the response should contain`("$.[1]name", "Opinion2") + } + } + } + + @Test + fun `I can get one opinion choice`() { + withIntegrationApplication { + `Given I have an opinion choice`("Opinion3", id = "347ec243-0e76-4ab5-9884-7bd503cf5ab5") + `When I send a GET request`("/opinions/347ec243-0e76-4ab5-9884-7bd503cf5ab5") { + } `Then the response should be` OK and { + `And the response should contain`("$.name", "Opinion3") + } + } + } + + @Test + fun `I can create opinion on article`() { + withIntegrationApplication { + `Given I have citizen`("Isaac", "Newton", id = "2f414045-95d9-42ca-a3a9-8cdde52ad253") + `Given I have an opinion choice`("Opinion4", id = "0f4f1721-3136-44f1-9f31-1459f3317b15") + `Given I have article`(id = "9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b", createdByUsername = "isaac-newton") + `When I send a PUT request`("/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b/opinions") { + `authenticated as`("Isaac", "Newton") + """ + { + "ids": [ + "0f4f1721-3136-44f1-9f31-1459f3317b15" + ] + } + """ + } `Then the response should be` Created + } + } + + @Test + fun `I can get all opinions of citizen filtered by target ids`() { + withIntegrationApplication { + `Given I have article`("4eb8a2c6-ba63-4c1e-919f-72017132a54e") + `Given I have citizen`("Albert", "Jacquard", id = "c6392fc4-56f5-461b-8015-953a4da3029f") + `Given I have an opinion choice`("Opinion5", id = "74d6e105-9aa6-4589-8776-82ce260bb6f4") + `Given I have opinion on article`( + "Opinion5", + article = "4eb8a2c6-ba63-4c1e-919f-72017132a54e", + Name("Albert", "Jacquard"), + id = "994660e7-e9f4-4ae9-9290-b34d78663c7a" + ) + `When I send a GET request`("/citizens/c6392fc4-56f5-461b-8015-953a4da3029f/opinions?id=4eb8a2c6-ba63-4c1e-919f-72017132a54e") { + `authenticated as`("Albert", "Jacquard") + } `Then the response should be` OK and { + `And the response should contain`("$[0].name", "Opinion5") + } + } + } + + @Test + fun `I can receive opinion aggregation with article`() { + withIntegrationApplication { + `Given I have an opinion choice`("Opinion6") + `Given I have an opinion choice`("Opinion7") + `Given I have an opinion choice`("Opinion8") + `Given I have citizen`("James", "Watt") + `Given I have citizen`("Paul", "Langevin") + `Given I have article`("bda8940a-6792-4f2b-936a-ba5c805c8487") + `Given I have opinion on article`( + "Opinion6", + article = "bda8940a-6792-4f2b-936a-ba5c805c8487", + Name("James", "Watt") + ) + `Given I have opinion on article`( + "Opinion7", + article = "bda8940a-6792-4f2b-936a-ba5c805c8487", + Name("James", "Watt") + ) + `Given I have opinion on article`( + "Opinion7", + article = "bda8940a-6792-4f2b-936a-ba5c805c8487", + Name("Paul", "Langevin") + ) + `When I send a GET request`("/articles/bda8940a-6792-4f2b-936a-ba5c805c8487") `Then the response should be` OK and { + `And the response should contain`("$.opinions.Opinion6", 1) + `And the response should contain`("$.opinions.Opinion7", 2) + } + } + } + + @Test + fun `I can get all opinion of one citizen`() { + withIntegrationApplication { + `Given I have citizen`("Albert", "Einstein", id = "c1542096-3431-432d-8e35-9dc071d4c818") + `Given I have an opinion choice`("Opinion9") + `Given I have article`("8651b530-ac1b-4214-a784-706781371074") + `Given I have opinion on article`( + "Opinion9", + article = "8651b530-ac1b-4214-a784-706781371074", + Name("Albert", "Einstein") + ) + `When I send a GET request`("/citizens/c1542096-3431-432d-8e35-9dc071d4c818/opinions/articles") { + `authenticated as`("Albert", "Einstein") + } `Then the response should be` OK and { + `And the response should contain`("$.result[0].name", "Opinion9") + `And the response should contain list`("$.result[*]", 1, 1) + } + } + } +} diff --git a/src/test/kotlin/integration/steps/given/Opinion.kt b/src/test/kotlin/integration/steps/given/Opinion.kt new file mode 100644 index 0000000..e55f6cb --- /dev/null +++ b/src/test/kotlin/integration/steps/given/Opinion.kt @@ -0,0 +1,53 @@ +package integration.steps.given + +import fr.dcproject.common.utils.toUUID +import fr.dcproject.component.article.ArticleRef +import fr.dcproject.component.citizen.CitizenI.Name +import fr.dcproject.component.citizen.CitizenRepository +import fr.dcproject.component.opinion.OpinionChoiceRepository +import fr.dcproject.component.opinion.OpinionRepositoryArticle +import fr.dcproject.component.opinion.entity.OpinionChoice +import fr.dcproject.component.opinion.entity.OpinionForUpdate +import io.ktor.server.testing.TestApplicationEngine +import org.koin.core.context.GlobalContext +import java.util.UUID + +fun TestApplicationEngine.`Given I have an opinion choice`( + name: String, + id: String? = null, +) { + createOpinionChoice(id?.toUUID(), name) +} + +fun createOpinionChoice( + id: UUID? = null, + name: String, +): OpinionChoice { + val opinionChoiceRepository: OpinionChoiceRepository by lazy { GlobalContext.get().koin.get() } + val opinionChoice = OpinionChoice( + id = id, + name = name, + target = listOf() + ) + return opinionChoiceRepository.upsertOpinionChoice(opinionChoice) +} + +fun `Given I have opinion on article`( + name: String, + article: String, + citizenName: Name, + id: String? = null +) { + val citizenRepository: CitizenRepository by lazy { GlobalContext.get().koin.get() } + val opinionRepositoryArticle: OpinionRepositoryArticle by lazy { GlobalContext.get().koin.get() } + val opinionChoiceRepository: OpinionChoiceRepository by lazy { GlobalContext.get().koin.get() } + val opinion = OpinionForUpdate( + id = id?.toUUID() ?: UUID.randomUUID(), + choice = opinionChoiceRepository.findOpinionsChoiceByName(name) + ?: error("Opinion Choice not exist"), + target = ArticleRef(article.toUUID()), + createdBy = citizenRepository.findByName(citizenName) + ?: error("Citizen not exist") + ) + opinionRepositoryArticle.addOpinion(opinion) +} diff --git a/src/test/resources/feature/opinion.feature b/src/test/resources/feature/opinion.feature index eb0bc57..777b6ba 100644 --- a/src/test/resources/feature/opinion.feature +++ b/src/test/resources/feature/opinion.feature @@ -1,4 +1,5 @@ @opinion +@disable Feature: Opinion Scenario: Can get all opinion choices