Refactoring Opinion Tests

upsert_opinion_choice
This commit is contained in:
2020-03-17 00:31:24 +01:00
parent 6b4a6f4075
commit 8c7e5bdf9b
9 changed files with 129 additions and 67 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;@opinion&quot; -Dstrict" /> <option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags=&quot;@opinion&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

@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test All SQL" type="DatabaseScript" folderName="SQL TEST" editBeforeRun="true"> <configuration default="false" name="Test All SQL" type="DatabaseScript" folderName="SQL TEST">
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/article/find_article_by_id.sql" /> <script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/article/find_article_by_id.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/article/find_articles.sql" /> <script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/article/find_articles.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/article/find_articles_versions_by_id.sql" /> <script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/article/find_articles_versions_by_id.sql" />
@@ -53,6 +53,7 @@
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/find_opinion_choices.sql" /> <script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/find_opinion_choices.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/find_opinion_by_id.sql" /> <script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/find_opinion_by_id.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/upsert_opinion.sql" /> <script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/upsert_opinion.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/upsert_opinion_choice.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/workgroup/find_workgroup_by_id.sql" /> <script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/workgroup/find_workgroup_by_id.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/workgroup/find_workgroups.sql" /> <script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/workgroup/find_workgroups.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/workgroup/upsert_workgroup.sql" /> <script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/workgroup/upsert_workgroup.sql" />

View File

@@ -9,6 +9,7 @@
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/find_opinion_choices.sql" /> <script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/find_opinion_choices.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/upsert_opinion.sql" /> <script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/upsert_opinion.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/find_opinion_by_opinion.sql" /> <script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/find_opinion_by_opinion.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/upsert_opinion_choice.sql" />
<script-file value="$PROJECT_DIR$/src/test/sql/opinion.sql" /> <script-file value="$PROJECT_DIR$/src/test/sql/opinion.sql" />
<script-mode>FILE</script-mode> <script-mode>FILE</script-mode>
<data-source id="a9a6d0e9-327d-4e7d-9b93-3cb6f7948866" namespace="database/&quot;test&quot;/schema/&quot;public&quot;" /> <data-source id="a9a6d0e9-327d-4e7d-9b93-3cb6f7948866" namespace="database/&quot;test&quot;/schema/&quot;public&quot;" />

View File

@@ -8,7 +8,7 @@ import fr.postgresjson.entity.mutable.EntityDeletedAtImp
import java.util.* import java.util.*
class OpinionChoice( class OpinionChoice(
id: UUID, id: UUID? = null,
val name: String, val name: String,
val target: List<String>? val target: List<String>?
) : OpinionChoiceRef(id), ) : OpinionChoiceRef(id),
@@ -16,5 +16,5 @@ class OpinionChoice(
EntityDeletedAt by EntityDeletedAtImp() EntityDeletedAt by EntityDeletedAtImp()
open class OpinionChoiceRef( open class OpinionChoiceRef(
id: UUID id: UUID?
) : UuidEntity(id) ) : UuidEntity(id ?: UUID.randomUUID())

View File

@@ -43,6 +43,12 @@ open class OpinionChoice(override val requester: Requester) : RepositoryI {
.selectOne( .selectOne(
"id" to id "id" to id
) )
fun upsertOpinionChoice(opinionChoice: OpinionChoiceEntity): OpinionChoiceEntity = requester
.getFunction("upsert_opinion_choice")
.selectOne(
"resource" to opinionChoice
)!!
} }
open class Opinion<T : TargetRef>(requester: Requester) : OpinionChoice(requester) { open class Opinion<T : TargetRef>(requester: Requester) : OpinionChoice(requester) {

View File

@@ -0,0 +1,20 @@
create or replace function upsert_opinion_choice(inout resource json)
language plpgsql as
$$
declare
_id uuid = coalesce((resource->>'id')::uuid, uuid_generate_v4());
begin
insert into opinion_choice (id, name, target)
select
_id,
name,
target
from json_populate_record(null::opinion_choice, resource)
on conflict (name) do update set
target = excluded.target;
select find_opinion_choice_by_id(_id) into resource;
end;
$$;
-- drop function if exists upsert_opinion_choice(json);

View File

@@ -1,11 +1,13 @@
package feature package feature
import fr.dcproject.entity.OpinionArticle import fr.dcproject.entity.OpinionArticle
import fr.dcproject.entity.OpinionChoice
import fr.dcproject.utils.toUUID import fr.dcproject.utils.toUUID
import io.cucumber.datatable.DataTable import io.cucumber.datatable.DataTable
import io.cucumber.java8.En import io.cucumber.java8.En
import org.koin.test.KoinTest import org.koin.test.KoinTest
import org.koin.test.get import org.koin.test.get
import java.util.*
import fr.dcproject.repository.Article as ArticleRepository import fr.dcproject.repository.Article as ArticleRepository
import fr.dcproject.repository.Citizen as CitizenRepository import fr.dcproject.repository.Citizen as CitizenRepository
import fr.dcproject.repository.OpinionArticle as OpinionRepository import fr.dcproject.repository.OpinionArticle as OpinionRepository
@@ -13,21 +15,50 @@ import fr.dcproject.repository.OpinionChoice as OpinionChoiceRepository
class OpinionSteps : En, KoinTest { class OpinionSteps : En, KoinTest {
init { init {
Given("I have the opinion {string} on article {string} created by {string}:") { opinionChoice: String, article: String, citizen: String, extraInfo: DataTable -> Given("I have an opinion choice {string}") { name: String ->
extraInfo.asMap<String, String>(String::class.java, String::class.java).let { val opinionChoice = OpinionChoice(
val opinion = OpinionArticle( name = name,
choice = get<OpinionChoiceRepository>().findOpinionsChoiceByName(opinionChoice) target = listOf()
?: error("Opinion Choice not exist"),
target = get<ArticleRepository>().findById(article.toUUID()) ?: error("Article not exist"),
createdBy = get<CitizenRepository>().findById(citizen.toUUID()) ?: error("Citizen not exist")
) )
get<OpinionRepository>().opinion(opinion) get<OpinionRepository>().upsertOpinionChoice(opinionChoice)
} }
Given("I have an opinion choice {string} with ID {string}") { name: String, id: String ->
val opinionChoice = OpinionChoice(
id = id.toUUID(),
name = name,
target = listOf()
)
get<OpinionRepository>().upsertOpinionChoice(opinionChoice)
}
Given("I have an opinion {string} on article {string} created by {word} {word}") { opinionChoiceName: String, articleId: String, firstName: String, lastName: String ->
createOpinion(opinionChoiceName, articleId, firstName, lastName)
}
Given("I have an opinion {string} on article {string} created by {word} {word} with ID {string}") { opinionChoiceName: String, articleId: String, firstName: String, lastName: String, id: String ->
createOpinion(opinionChoiceName, articleId, firstName, lastName, id)
} }
Given("I have an opinion") { extraInfo: DataTable -> Given("I have an opinion") { extraInfo: DataTable ->
extraInfo.asMap<String, String>(String::class.java, String::class.java)?.let { params -> createOpinionOnArticle(extraInfo)
val username = params["createdBy"]?.toLowerCase()?.replace(' ', '-') }
}
private fun createOpinion(opinionChoiceName: String, articleId: String, firstName: String, lastName: String, id: String? = null) {
val opinion = OpinionArticle(
id = id?.toUUID() ?: UUID.randomUUID(),
choice = get<OpinionChoiceRepository>().findOpinionsChoiceByName(opinionChoiceName)
?: error("Opinion Choice not exist"),
target = get<ArticleRepository>().findById(articleId.toUUID()) ?: error("Article not exist"),
createdBy = get<CitizenRepository>().findByUsername("$firstName-$lastName".toLowerCase().replace(' ', '-')) ?: error("Citizen not exist")
)
get<OpinionRepository>().opinion(opinion)
}
private fun createOpinionOnArticle(extraInfo: DataTable? = null) {
val params = extraInfo?.asMap<String, String>(String::class.java, String::class.java)
val username = params?.get("createdBy")?.toLowerCase()?.replace(' ', '-')
?: error("You must provide the 'createdBy' parameter") ?: error("You must provide the 'createdBy' parameter")
val opinion = OpinionArticle( val opinion = OpinionArticle(
choice = params["opinion"]?.let { choice = params["opinion"]?.let {
@@ -41,5 +72,3 @@ class OpinionSteps : En, KoinTest {
get<OpinionRepository>().opinion(opinion) get<OpinionRepository>().opinion(opinion)
} }
} }
}
}

View File

@@ -1,63 +1,73 @@
@opinion @opinion
Feature: Opinion Feature: Opinion
Scenario: Can get one opinion Choices
When I send a GET request to "/opinions/6e978eb5-3c48-0def-b093-e01f43983adb"
Then the response status code should be 200
And the JSON should contain:
| name | Opinion1 |
Scenario: Can get all opinion choices Scenario: Can get all opinion choices
Given I have an opinion choice "Opinion1"
And I have an opinion choice "Opinion2"
When I send a GET request to "/opinions" When I send a GET request to "/opinions"
Then the response status code should be 200 Then the response status code should be 200
And the JSON should contain: And the JSON should contain:
| [0]name | Opinion1 | | [0]name | Opinion1 |
| [1]name | Opinion2 |
Scenario: Can get one opinion Choices
Given I have an opinion choice "Opinion3" with ID "347ec243-0e76-4ab5-9884-7bd503cf5ab5"
When I send a GET request to "/opinions/347ec243-0e76-4ab5-9884-7bd503cf5ab5"
Then the response status code should be 200
And the JSON should contain:
| name | Opinion3 |
Scenario: Can create opinion on article Scenario: Can create opinion on article
Given I have citizen: Given I have citizen Isaac Newton with ID "2f414045-95d9-42ca-a3a9-8cdde52ad253"
| id | 2f414045-95d9-42ca-a3a9-8cdde52ad253 |
| firstName | Isaac |
| lastName | Newton |
And I am authenticated as Isaac Newton And I am authenticated as Isaac Newton
And I have article And I have article
| id | 9226c1a3-8091-c3fa-7d0d-c2e98c9bee7 | | id | 9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b |
| createdBy | Isaac Newton |
And I have an opinion
| opinion | Opinion1 |
| article | 9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b |
| createdBy | Isaac Newton | | createdBy | Isaac Newton |
And I have an opinion choice "Opinion4" with ID "0f4f1721-3136-44f1-9f31-1459f3317b15"
And I have an opinion "Opinion4" on article "9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b" created by Isaac Newton with ID "74e93e12-556b-4399-95a6-04f93a4dd66c"
When I send a PUT request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b/opinions" with body: When I send a PUT request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b/opinions" with body:
""" """
{ {
"opinion_choice": "6e978eb5-3c48-0def-b093-e01f43983adb" "opinion_choice": "0f4f1721-3136-44f1-9f31-1459f3317b15"
} }
""" """
Then the response status code should be 201 Then the response status code should be 201
Scenario: Can I get all opinions of citizen filtered by target ids Scenario: Can I get all opinions of citizen filtered by target ids
When I send a GET request to "/citizens/6434f4f9-f570-f22a-c134-8668350651ff/opinions?id=9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b" Given I have article with ID "4eb8a2c6-ba63-4c1e-919f-72017132a54e"
And I have citizen Albert Jacquard with ID "c6392fc4-56f5-461b-8015-953a4da3029f"
And I am authenticated as Albert Jacquard
And I have an opinion choice "Opinion5" with ID "74d6e105-9aa6-4589-8776-82ce260bb6f4"
And I have an opinion "Opinion5" on article "4eb8a2c6-ba63-4c1e-919f-72017132a54e" created by Albert Jacquard with ID "994660e7-e9f4-4ae9-9290-b34d78663c7a"
When I send a GET request to "/citizens/c6392fc4-56f5-461b-8015-953a4da3029f/opinions?id=4eb8a2c6-ba63-4c1e-919f-72017132a54e"
Then the response status code should be 200 Then the response status code should be 200
And the JSON should contain: And the JSON should contain:
| [0].name | Opinion2 | | [0].name | Opinion5 |
Scenario: Can recieve opinion aggregation with article Scenario: Can recieve opinion aggregation with article
When I send a GET request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b" Given I have an opinion choice "Opinion6"
And I have an opinion choice "Opinion7"
And I have an opinion choice "Opinion8"
And I have citizen James Watt
And I have citizen Paul Langevin
And I have article with ID "bda8940a-6792-4f2b-936a-ba5c805c8487"
And I have an opinion "Opinion6" on article "bda8940a-6792-4f2b-936a-ba5c805c8487" created by James Watt
And I have an opinion "Opinion7" on article "bda8940a-6792-4f2b-936a-ba5c805c8487" created by James Watt
And I have an opinion "Opinion7" on article "bda8940a-6792-4f2b-936a-ba5c805c8487" created by Paul Langevin
When I send a GET request to "/articles/bda8940a-6792-4f2b-936a-ba5c805c8487"
Then the response status code should be 200 Then the response status code should be 200
And the JSON should contain: And the JSON should contain:
| opinions.Opinion2 | 1 | | opinions.Opinion6 | 1 |
| opinions.Opinion7 | 2 |
Scenario: Can get all opinion of one citizen Scenario: Can get all opinion of one citizen
Given I have citizen: Given I have citizen Albert Einstein with ID "c1542096-3431-432d-8e35-9dc071d4c818"
| id | c1542096-3431-432d-8e35-9dc071d4c818 |
| firstName | Albert |
| lastName | Einstein |
And I am authenticated as Albert Einstein And I am authenticated as Albert Einstein
And I have an opinion And I have an opinion choice "Opinion9"
| opinion | Opinion1 | And I have article with ID "8651b530-ac1b-4214-a784-706781371074"
| article | 9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b | And I have an opinion "Opinion9" on article "8651b530-ac1b-4214-a784-706781371074" created by Albert Einstein
| createdBy | Albert Einstein |
When I send a GET request to "/citizens/c1542096-3431-432d-8e35-9dc071d4c818/opinions/articles" When I send a GET request to "/citizens/c1542096-3431-432d-8e35-9dc071d4c818/opinions/articles"
Then the response status code should be 200 Then the response status code should be 200
And the JSON element result should have 1 items And the JSON element result should have 1 items
And the JSON should contain: And the JSON should contain:
| result[0].name | Opinion1 | | result[0].name | Opinion9 |

View File

@@ -58,15 +58,10 @@ begin
-- upsert article -- upsert article
select upsert_article(created_article) into created_article; select upsert_article(created_article) into created_article;
select (h->>'id')::uuid into opinion_choice1_id from upsert_opinion_choice('{"name": "Opinion1", "target":["article"]}') h;
insert into opinion_choice(id, name, target) assert opinion_choice1_id is not null, 'Opinion choice must be return json with id';
values (opinion_choice1_id, 'Opinion1', '{article}'); select (h->>'id')::uuid into opinion_choice2_id from upsert_opinion_choice('{"name": "Opinion2"}') h;
perform upsert_opinion_choice('{"name": "Opinion3", "target":["article"]}') h;
insert into opinion_choice(id, name)
values (opinion_choice2_id, 'Opinion2');
insert into opinion_choice(name, target)
values ('Opinion3', '{article}');
perform upsert_opinion( perform upsert_opinion(
resource => json_build_object( resource => json_build_object(