Refactoring Opinion Tests
upsert_opinion_choice
This commit is contained in:
2
.idea/runConfigurations/Opinion_Tests.xml
generated
2
.idea/runConfigurations/Opinion_Tests.xml
generated
@@ -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="@opinion" -Dstrict" />
|
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags="@opinion"" />
|
||||||
<option name="PARAMETERS" value="" />
|
<option name="PARAMETERS" value="" />
|
||||||
<option name="TEST_SEARCH_SCOPE">
|
<option name="TEST_SEARCH_SCOPE">
|
||||||
<value defaultName="wholeProject" />
|
<value defaultName="wholeProject" />
|
||||||
|
|||||||
3
.idea/runConfigurations/Test_All_SQL.xml
generated
3
.idea/runConfigurations/Test_All_SQL.xml
generated
@@ -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" />
|
||||||
|
|||||||
1
.idea/runConfigurations/Test_Opinions.xml
generated
1
.idea/runConfigurations/Test_Opinions.xml
generated
@@ -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/"test"/schema/"public"" />
|
<data-source id="a9a6d0e9-327d-4e7d-9b93-3cb6f7948866" namespace="database/"test"/schema/"public"" />
|
||||||
|
|||||||
@@ -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())
|
||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -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,33 +15,60 @@ 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"),
|
get<OpinionRepository>().upsertOpinionChoice(opinionChoice)
|
||||||
createdBy = get<CitizenRepository>().findById(citizen.toUUID()) ?: error("Citizen not exist")
|
}
|
||||||
)
|
|
||||||
get<OpinionRepository>().opinion(opinion)
|
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(' ', '-')
|
|
||||||
?: error("You must provide the 'createdBy' parameter")
|
|
||||||
val opinion = OpinionArticle(
|
|
||||||
choice = params["opinion"]?.let {
|
|
||||||
get<OpinionChoiceRepository>().findOpinionsChoiceByName(it) ?: error("Opinion Choice not exist")
|
|
||||||
} ?: error("You must provide the 'opinion' parameter"),
|
|
||||||
target = params["article"]?.let {
|
|
||||||
get<ArticleRepository>().findById(it.toUUID()) ?: error("Article not exist")
|
|
||||||
} ?: error("You must provide the 'article' parameter"),
|
|
||||||
createdBy = get<CitizenRepository>().findByUsername(username) ?: error("Citizen not exist")
|
|
||||||
)
|
|
||||||
get<OpinionRepository>().opinion(opinion)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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")
|
||||||
|
val opinion = OpinionArticle(
|
||||||
|
choice = params["opinion"]?.let {
|
||||||
|
get<OpinionChoiceRepository>().findOpinionsChoiceByName(it) ?: error("Opinion Choice not exist")
|
||||||
|
} ?: error("You must provide the 'opinion' parameter"),
|
||||||
|
target = params["article"]?.let {
|
||||||
|
get<ArticleRepository>().findById(it.toUUID()) ?: error("Article not exist")
|
||||||
|
} ?: error("You must provide the 'article' parameter"),
|
||||||
|
createdBy = get<CitizenRepository>().findByUsername(username) ?: error("Citizen not exist")
|
||||||
|
)
|
||||||
|
get<OpinionRepository>().opinion(opinion)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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 |
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user