#57 I can filter articles by workgroup
update lib "postgres-json:1.2.1"
This commit is contained in:
16
.idea/codeStyles/Project.xml
generated
16
.idea/codeStyles/Project.xml
generated
@@ -2,6 +2,22 @@
|
|||||||
<code_scheme name="Project" version="173">
|
<code_scheme name="Project" version="173">
|
||||||
<option name="LINE_SEPARATOR" value=" " />
|
<option name="LINE_SEPARATOR" value=" " />
|
||||||
<JetCodeStyleSettings>
|
<JetCodeStyleSettings>
|
||||||
|
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||||
|
<value>
|
||||||
|
<package name="java.util" alias="false" withSubpackages="false" />
|
||||||
|
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
||||||
|
<package name="io.ktor" alias="false" withSubpackages="true" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||||
|
<value>
|
||||||
|
<package name="" alias="false" withSubpackages="true" />
|
||||||
|
<package name="java" alias="false" withSubpackages="true" />
|
||||||
|
<package name="javax" alias="false" withSubpackages="true" />
|
||||||
|
<package name="kotlin" alias="false" withSubpackages="true" />
|
||||||
|
<package name="" alias="true" withSubpackages="true" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
</JetCodeStyleSettings>
|
</JetCodeStyleSettings>
|
||||||
<PostgresCodeStyleSettings version="2">
|
<PostgresCodeStyleSettings version="2">
|
||||||
|
|||||||
9
.idea/runConfigurations/Check.xml
generated
Normal file
9
.idea/runConfigurations/Check.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Check" type="CompoundRunConfigurationType">
|
||||||
|
<toRun name="Unit Tests (offline)" type="JUnit" />
|
||||||
|
<toRun name="Cucumber Tests (offline)" type="JUnit" />
|
||||||
|
<toRun name="Test All SQL" type="ShConfigurationType" />
|
||||||
|
<toRun name="Lint" type="GradleRunConfiguration" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
</extension>
|
</extension>
|
||||||
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
|
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All Tests + Lint" run_configuration_type="JUnit" />
|
<option name="RunConfigurationTask" enabled="true" />
|
||||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Sonarqube" run_configuration_type="GradleRunConfiguration" />
|
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Sonarqube" run_configuration_type="GradleRunConfiguration" />
|
||||||
</method>
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
2
.idea/runConfigurations/Lint__Test___Run.xml
generated
2
.idea/runConfigurations/Lint__Test___Run.xml
generated
@@ -32,7 +32,7 @@
|
|||||||
</extension>
|
</extension>
|
||||||
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
|
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All Tests + Lint" run_configuration_type="JUnit" />
|
<option name="RunConfigurationTask" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="All Tests + Lint" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
|
<configuration default="false" name="Unit Tests" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
|
||||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||||
<useClassPathOnly />
|
<useClassPathOnly />
|
||||||
<option name="PACKAGE_NAME" value="fr.dcproject" />
|
<option name="PACKAGE_NAME" value="fr.dcproject" />
|
||||||
@@ -17,8 +17,6 @@
|
|||||||
<dir value="$PROJECT_DIR$" />
|
<dir value="$PROJECT_DIR$" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Lint" run_configuration_type="GradleRunConfiguration" />
|
|
||||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Test All SQL" run_configuration_type="ShConfigurationType" />
|
|
||||||
</method>
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="All Tests + Lint (offline)" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
|
<configuration default="false" name="Unit Tests (offline)" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
|
||||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||||
<useClassPathOnly />
|
<useClassPathOnly />
|
||||||
<option name="PACKAGE_NAME" value="fr.dcproject" />
|
<option name="PACKAGE_NAME" value="fr.dcproject" />
|
||||||
@@ -18,8 +18,6 @@
|
|||||||
<tag value="!online" />
|
<tag value="!online" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Lint" run_configuration_type="GradleRunConfiguration" />
|
|
||||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Test All SQL" run_configuration_type="ShConfigurationType" />
|
|
||||||
</method>
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
||||||
3
Makefile
3
Makefile
@@ -42,6 +42,9 @@ f: fixtures
|
|||||||
fixtures: ## Import fixtures
|
fixtures: ## Import fixtures
|
||||||
bash src/main/resources/sql/fixtures/fixtures.sh
|
bash src/main/resources/sql/fixtures/fixtures.sh
|
||||||
|
|
||||||
|
test-sql: ## Test sql
|
||||||
|
cd src/test/sql/ ; bash test.sh 1
|
||||||
|
|
||||||
v: vertion
|
v: vertion
|
||||||
|
|
||||||
vertion: ## Show current version
|
vertion: ## Show current version
|
||||||
|
|||||||
@@ -64,6 +64,11 @@ val sourcesJar by tasks.creating(Jar::class) {
|
|||||||
archiveClassifier.set("sources")
|
archiveClassifier.set("sources")
|
||||||
from(sourceSets.getByName("main").allSource)
|
from(sourceSets.getByName("main").allSource)
|
||||||
}
|
}
|
||||||
|
tasks.test {
|
||||||
|
useJUnit()
|
||||||
|
useJUnitPlatform()
|
||||||
|
// maxHeapSize = "1G"
|
||||||
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
if (versioning.info.dirty == false) {
|
if (versioning.info.dirty == false) {
|
||||||
@@ -87,7 +92,7 @@ publishing {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LoggerFactory.getLogger("gradle")
|
LoggerFactory.getLogger("gradle")
|
||||||
.warn("The git is DIRTY !!! You cannot publish this crap! (${versioning.info.full})")
|
.warn("The git is DIRTY (${versioning.info.full})")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +138,7 @@ dependencies {
|
|||||||
implementation("net.pearx.kasechange:kasechange-jvm:1.1.0")
|
implementation("net.pearx.kasechange:kasechange-jvm:1.1.0")
|
||||||
implementation("com.auth0:java-jwt:3.8.2")
|
implementation("com.auth0:java-jwt:3.8.2")
|
||||||
implementation("com.github.jasync-sql:jasync-postgresql:1.0.7")
|
implementation("com.github.jasync-sql:jasync-postgresql:1.0.7")
|
||||||
implementation("com.github.flecomte:postgres-json:1.1.1")
|
implementation("com.github.flecomte:postgres-json:1.2.1")
|
||||||
implementation("com.github.flecomte:ktor-voter:1.0.1")
|
implementation("com.github.flecomte:ktor-voter:1.0.1")
|
||||||
implementation("com.sendgrid:sendgrid-java:4.4.1")
|
implementation("com.sendgrid:sendgrid-java:4.4.1")
|
||||||
implementation("io.lettuce:lettuce-core:5.2.2.RELEASE")
|
implementation("io.lettuce:lettuce-core:5.2.2.RELEASE")
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import fr.postgresjson.entity.mutable.UuidEntityVersioning
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class Article(
|
class Article(
|
||||||
id: UUID = UUID.randomUUID(),
|
id: UUID? = null,
|
||||||
title: String,
|
title: String,
|
||||||
override var anonymous: Boolean = true,
|
override var anonymous: Boolean = true,
|
||||||
override var content: String,
|
override var content: String,
|
||||||
@@ -27,8 +27,22 @@ class Article(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ArticleForUpdate(
|
||||||
|
id: UUID?,
|
||||||
|
val title: String,
|
||||||
|
val anonymous: Boolean = true,
|
||||||
|
val content: String,
|
||||||
|
val description: String,
|
||||||
|
tags: List<String> = emptyList(),
|
||||||
|
val draft: Boolean = false,
|
||||||
|
val createdBy: CitizenRef,
|
||||||
|
val workgroup: WorkgroupRef? = null
|
||||||
|
) : ArticleRefVersioning(id) {
|
||||||
|
val tags: List<String> = tags.distinct()
|
||||||
|
}
|
||||||
|
|
||||||
open class ArticleSimple(
|
open class ArticleSimple(
|
||||||
id: UUID = UUID.randomUUID(),
|
id: UUID? = null,
|
||||||
override var title: String,
|
override var title: String,
|
||||||
override val createdBy: CitizenBasic,
|
override val createdBy: CitizenBasic,
|
||||||
override var draft: Boolean = false,
|
override var draft: Boolean = false,
|
||||||
@@ -43,14 +57,14 @@ open class ArticleSimple(
|
|||||||
Opinionable by OpinionableImp()
|
Opinionable by OpinionableImp()
|
||||||
|
|
||||||
open class ArticleRefVersioning(
|
open class ArticleRefVersioning(
|
||||||
id: UUID = UUID.randomUUID(),
|
id: UUID? = null,
|
||||||
versionNumber: Int? = null,
|
versionNumber: Int? = null,
|
||||||
versionId: UUID = UUID.randomUUID()
|
versionId: UUID = UUID.randomUUID()
|
||||||
) : ArticleRef(id),
|
) : ArticleRef(id),
|
||||||
EntityVersioning<UUID, Int> by UuidEntityVersioning(versionNumber, versionId)
|
EntityVersioning<UUID, Int> by UuidEntityVersioning(versionNumber, versionId)
|
||||||
|
|
||||||
open class ArticleRef(
|
open class ArticleRef(
|
||||||
id: UUID = UUID.randomUUID()
|
id: UUID? = null
|
||||||
) : ArticleI, TargetRef(id)
|
) : ArticleI, TargetRef(id)
|
||||||
|
|
||||||
interface ArticleI : UuidEntityI, TargetI
|
interface ArticleI : UuidEntityI, TargetI
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package fr.dcproject.entity
|
|||||||
import fr.postgresjson.entity.immutable.*
|
import fr.postgresjson.entity.immutable.*
|
||||||
import fr.postgresjson.entity.mutable.EntityDeletedAt
|
import fr.postgresjson.entity.mutable.EntityDeletedAt
|
||||||
import fr.postgresjson.entity.mutable.EntityDeletedAtImp
|
import fr.postgresjson.entity.mutable.EntityDeletedAtImp
|
||||||
|
import fr.postgresjson.entity.mutable.EntityVersioning
|
||||||
|
import fr.postgresjson.entity.mutable.UuidEntityVersioning
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class Constitution(
|
class Constitution(
|
||||||
@@ -41,7 +43,7 @@ open class ConstitutionSimple<Cr : CitizenRefWithUser, T : ConstitutionSimple.Ti
|
|||||||
override val createdBy: Cr,
|
override val createdBy: Cr,
|
||||||
versionId: UUID = UUID.randomUUID()
|
versionId: UUID = UUID.randomUUID()
|
||||||
) : ConstitutionRef(id),
|
) : ConstitutionRef(id),
|
||||||
EntityVersioning<UUID, Int?> by UuidEntityVersioning(versionId = versionId),
|
EntityVersioning<UUID, Int> by UuidEntityVersioning(versionId = versionId),
|
||||||
EntityCreatedAt by EntityCreatedAtImp(),
|
EntityCreatedAt by EntityCreatedAtImp(),
|
||||||
EntityCreatedBy<Cr> by EntityCreatedByImp(createdBy),
|
EntityCreatedBy<Cr> by EntityCreatedByImp(createdBy),
|
||||||
EntityDeletedAt by EntityDeletedAtImp() {
|
EntityDeletedAt by EntityDeletedAtImp() {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface ExtraI<T : TargetI, C : CitizenI> :
|
|||||||
val target: T
|
val target: T
|
||||||
}
|
}
|
||||||
|
|
||||||
open class TargetRef(id: UUID = UUID.randomUUID(), reference: String = "") : TargetI, UuidEntity(id) {
|
open class TargetRef(id: UUID? = null, reference: String = "") : TargetI, UuidEntity(id) {
|
||||||
|
|
||||||
final override val reference: String
|
final override val reference: String
|
||||||
get() = if (field != "") field else TargetI.getReference(this)
|
get() = if (field != "") field else TargetI.getReference(this)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package fr.dcproject.repository
|
package fr.dcproject.repository
|
||||||
|
|
||||||
import fr.dcproject.entity.ArticleFull
|
import fr.dcproject.entity.ArticleForUpdate
|
||||||
import fr.dcproject.entity.ArticleSimple
|
import fr.dcproject.entity.ArticleSimple
|
||||||
import fr.postgresjson.connexion.Paginated
|
import fr.postgresjson.connexion.Paginated
|
||||||
import fr.postgresjson.connexion.Requester
|
import fr.postgresjson.connexion.Requester
|
||||||
@@ -42,13 +42,14 @@ class Article(override var requester: Requester) : RepositoryI {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun upsert(article: ArticleFull): ArticleEntity? {
|
fun upsert(article: ArticleForUpdate): ArticleEntity? {
|
||||||
return requester
|
return requester
|
||||||
.getFunction("upsert_article")
|
.getFunction("upsert_article")
|
||||||
.selectOne("resource" to article)
|
.selectOne("resource" to article)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Filter(
|
class Filter(
|
||||||
val createdById: String? = null
|
val createdById: String? = null,
|
||||||
|
val workgroupId: String? = null
|
||||||
) : Parameter
|
) : Parameter
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package fr.dcproject.routes
|
|||||||
|
|
||||||
import fr.dcproject.citizen
|
import fr.dcproject.citizen
|
||||||
import fr.dcproject.citizenOrNull
|
import fr.dcproject.citizenOrNull
|
||||||
|
import fr.dcproject.entity.ArticleForUpdate
|
||||||
import fr.dcproject.entity.CitizenRef
|
import fr.dcproject.entity.CitizenRef
|
||||||
import fr.dcproject.entity.WorkgroupRef
|
import fr.dcproject.entity.WorkgroupRef
|
||||||
import fr.dcproject.entity.WorkgroupSimple
|
import fr.dcproject.entity.WorkgroupSimple
|
||||||
@@ -39,7 +40,8 @@ object ArticlesPaths {
|
|||||||
val sort: String? = null,
|
val sort: String? = null,
|
||||||
val direction: RepositoryI.Direction? = null,
|
val direction: RepositoryI.Direction? = null,
|
||||||
val search: String? = null,
|
val search: String? = null,
|
||||||
val createdBy: String? = null
|
val createdBy: String? = null,
|
||||||
|
val workgroup: String? = null
|
||||||
) {
|
) {
|
||||||
val page: Int = if (page < 1) 1 else page
|
val page: Int = if (page < 1) 1 else page
|
||||||
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
|
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
|
||||||
@@ -62,7 +64,7 @@ object ArticlesPaths {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Location("/articles")
|
@Location("/articles")
|
||||||
class PostArticleRequest: KoinComponent {
|
class PostArticleRequest : KoinComponent {
|
||||||
class Article(
|
class Article(
|
||||||
val id: UUID?,
|
val id: UUID?,
|
||||||
val title: String,
|
val title: String,
|
||||||
@@ -77,8 +79,8 @@ object ArticlesPaths {
|
|||||||
|
|
||||||
private val workgroupRepository: WorkgroupRepository by inject()
|
private val workgroupRepository: WorkgroupRepository by inject()
|
||||||
|
|
||||||
suspend fun getNewArticle(call: ApplicationCall): ArticleEntity = call.receive<Article>().run {
|
suspend fun getNewArticle(call: ApplicationCall): ArticleForUpdate = call.receive<Article>().run {
|
||||||
ArticleEntity(
|
ArticleForUpdate(
|
||||||
id ?: UUID.randomUUID(),
|
id ?: UUID.randomUUID(),
|
||||||
title,
|
title,
|
||||||
anonymous,
|
anonymous,
|
||||||
@@ -98,8 +100,14 @@ object ArticlesPaths {
|
|||||||
@KtorExperimentalLocationsAPI
|
@KtorExperimentalLocationsAPI
|
||||||
fun Route.article(repo: ArticleRepository, viewManager: ArticleViewManager) {
|
fun Route.article(repo: ArticleRepository, viewManager: ArticleViewManager) {
|
||||||
get<ArticlesPaths.ArticlesRequest> {
|
get<ArticlesPaths.ArticlesRequest> {
|
||||||
val articles =
|
val articles = repo.find(
|
||||||
repo.find(it.page, it.limit, it.sort, it.direction, it.search, Filter(createdById = it.createdBy))
|
it.page,
|
||||||
|
it.limit,
|
||||||
|
it.sort,
|
||||||
|
it.direction,
|
||||||
|
it.search,
|
||||||
|
Filter(createdById = it.createdBy, workgroupId = it.workgroup)
|
||||||
|
)
|
||||||
assertCan(VIEW, articles.result)
|
assertCan(VIEW, articles.result)
|
||||||
call.respond(articles)
|
call.respond(articles)
|
||||||
}
|
}
|
||||||
@@ -127,9 +135,9 @@ fun Route.article(repo: ArticleRepository, viewManager: ArticleViewManager) {
|
|||||||
post<ArticlesPaths.PostArticleRequest> {
|
post<ArticlesPaths.PostArticleRequest> {
|
||||||
it.getNewArticle(call).also { article ->
|
it.getNewArticle(call).also { article ->
|
||||||
assertCan(CREATE, article)
|
assertCan(CREATE, article)
|
||||||
repo.upsert(article)
|
val newArticle = repo.upsert(article) ?: error("Article not updated")
|
||||||
call.respond(article)
|
call.respond(article)
|
||||||
raiseEvent(ArticleUpdate.event, ArticleUpdate(article))
|
raiseEvent(ArticleUpdate.event, ArticleUpdate(newArticle))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -218,6 +218,14 @@ paths:
|
|||||||
- $ref: '#/components/parameters/direction'
|
- $ref: '#/components/parameters/direction'
|
||||||
- $ref: '#/components/parameters/search'
|
- $ref: '#/components/parameters/search'
|
||||||
- $ref: '#/components/parameters/createdBy'
|
- $ref: '#/components/parameters/createdBy'
|
||||||
|
- name: workgroup
|
||||||
|
in: query
|
||||||
|
description: ID of workgroup
|
||||||
|
example: 82a0e60a-bb55-dbc0-1c3d-0a804df2b5df
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: The Article objects
|
description: The Article objects
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ begin
|
|||||||
from article a
|
from article a
|
||||||
where (_search is null or _search = '' or a ==> dsl.multi_match('{title^3, content, description, tags}', _search))
|
where (_search is null or _search = '' or a ==> dsl.multi_match('{title^3, content, description, tags}', _search))
|
||||||
and (_filter->>'created_by_id' is null or a.created_by_id = (_filter->>'created_by_id')::uuid)
|
and (_filter->>'created_by_id' is null or a.created_by_id = (_filter->>'created_by_id')::uuid)
|
||||||
|
and (_filter->>'workgroup_id' is null or a.workgroup_id = (_filter->>'workgroup_id')::uuid)
|
||||||
and a.last_version = true
|
and a.last_version = true
|
||||||
)
|
)
|
||||||
into resource, total
|
into resource, total
|
||||||
@@ -33,6 +34,7 @@ begin
|
|||||||
or a ==> dsl.multi_match('{title^3, content, description, tags}', _search)
|
or a ==> dsl.multi_match('{title^3, content, description, tags}', _search)
|
||||||
)
|
)
|
||||||
and (_filter->>'created_by_id' is null or a.created_by_id = (_filter->>'created_by_id')::uuid)
|
and (_filter->>'created_by_id' is null or a.created_by_id = (_filter->>'created_by_id')::uuid)
|
||||||
|
and (_filter->>'workgroup_id' is null or a.workgroup_id = (_filter->>'workgroup_id')::uuid)
|
||||||
and a.last_version = true
|
and a.last_version = true
|
||||||
|
|
||||||
order by
|
order by
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ class ArticleSteps : En, KoinTest {
|
|||||||
createArticle(id = UUID.fromString(id))
|
createArticle(id = UUID.fromString(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Given("I have article created by workgroup ID {string}") { id: String ->
|
||||||
|
createArticle(workgroup = WorkgroupRef(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)
|
||||||
}
|
}
|
||||||
@@ -39,7 +43,7 @@ class ArticleSteps : En, KoinTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createArticle(extraData: DataTable? = null, id: UUID? = null) {
|
private fun createArticle(extraData: DataTable? = null, id: UUID? = null, workgroup: WorkgroupRef? = 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())
|
||||||
@@ -63,12 +67,13 @@ class ArticleSteps : En, KoinTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val article = ArticleEntity(
|
val article = ArticleForUpdate(
|
||||||
id = id ?: params?.get("id")?.toUUID() ?: UUID.randomUUID(),
|
id = id ?: params?.get("id")?.toUUID(),
|
||||||
title = "hello",
|
title = "hello",
|
||||||
content = "bla bla bla",
|
content = "bla bla bla",
|
||||||
description = "A super article",
|
description = "A super article",
|
||||||
createdBy = createdBy
|
createdBy = createdBy,
|
||||||
|
workgroup = workgroup
|
||||||
)
|
)
|
||||||
get<ArticleRepository>().upsert(article)
|
get<ArticleRepository>().upsert(article)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,18 @@ Feature: articles routes
|
|||||||
When I send a GET request to "/articles"
|
When I send a GET request to "/articles"
|
||||||
Then the response status code should be 200
|
Then the response status code should be 200
|
||||||
|
|
||||||
|
Scenario: Can get articles filtered by workgroup
|
||||||
|
Given I have 3 article
|
||||||
|
And I have workgroup:
|
||||||
|
| id | 2bccd5a7-9082-4b31-88f8-e25d70b22b12 |
|
||||||
|
| name | Les papy |
|
||||||
|
And I have article created by workgroup ID "2bccd5a7-9082-4b31-88f8-e25d70b22b12"
|
||||||
|
When I send a GET request to "/articles?workgroup=2bccd5a7-9082-4b31-88f8-e25d70b22b12"
|
||||||
|
Then the response status code should be 200
|
||||||
|
And the JSON should contain:
|
||||||
|
| total | 1 |
|
||||||
|
| result[0]workgroup.name | Les papy |
|
||||||
|
|
||||||
Scenario: Can get versions of article by the id
|
Scenario: Can get versions of article by the id
|
||||||
Given I have article
|
Given I have article
|
||||||
| id | 13e6091c-8fed-4600-b079-a97a6b7a9800 |
|
| id | 13e6091c-8fed-4600-b079-a97a6b7a9800 |
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ do
|
|||||||
$$
|
$$
|
||||||
declare
|
declare
|
||||||
_citizen_id uuid := fixture_citizen();
|
_citizen_id uuid := fixture_citizen();
|
||||||
|
_workgroup_id uuid := fixture_workgroup(_citizen_id => _citizen_id);
|
||||||
created_article json := '{"version_id":"933b6a1b-50c9-42b6-989f-c02a57814ef9", "title": "Love the world", "anonymous": false, "content": "bla bal bla", "tags": ["love", "test"], "draft":false}';
|
created_article json := '{"version_id":"933b6a1b-50c9-42b6-989f-c02a57814ef9", "title": "Love the world", "anonymous": false, "content": "bla bal bla", "tags": ["love", "test"], "draft":false}';
|
||||||
|
created_article_grouped json := '{"version_id":"35f5c4c3-0629-4405-9956-12557020c9f5", "title": "Love my group", "anonymous": false, "content": "groupy groupy", "tags": ["love", "group"], "draft":false}';
|
||||||
created_article_v2 json;
|
created_article_v2 json;
|
||||||
first_article_id uuid;
|
first_article_id uuid;
|
||||||
second_article_id uuid;
|
second_article_id uuid;
|
||||||
@@ -25,12 +27,21 @@ begin
|
|||||||
assert (created_article_v2->>'last_version')::bool = true, 'The second insert must be set to the last version';
|
assert (created_article_v2->>'last_version')::bool = true, 'The second insert must be set to the last version';
|
||||||
second_article_id = (created_article_v2->>'id')::uuid;
|
second_article_id = (created_article_v2->>'id')::uuid;
|
||||||
|
|
||||||
|
created_article_grouped := jsonb_set(created_article_grouped::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
|
||||||
|
created_article_grouped := jsonb_set(created_article_grouped::jsonb, '{workgroup}'::text[], jsonb_build_object('id', _workgroup_id::text), true)::json;
|
||||||
|
select upsert_article(created_article_grouped) into created_article_grouped;
|
||||||
|
|
||||||
-- get articles versions by version_id
|
-- get articles versions by version_id
|
||||||
select resource, total into selected_article, selected_total from find_articles_versions_by_version_id((created_article->>'version_id')::uuid);
|
select resource, total into selected_article, selected_total from find_articles_versions_by_version_id((created_article->>'version_id')::uuid);
|
||||||
assert selected_article#>>'{0,title}' = 'Love the world', format('title must be "Love the world", %s', selected_article#>>'{0,title}');
|
assert selected_article#>>'{0,title}' = 'Love the world', format('title must be "Love the world", %s', selected_article#>>'{0,title}');
|
||||||
assert (selected_article#>>'{0,version_number}')::int = 2, format('version_id must be 2, %s instead', selected_article#>>'{0,version_number}');
|
assert (selected_article#>>'{0,version_number}')::int = 2, format('version_id must be 2, %s instead', selected_article#>>'{0,version_number}');
|
||||||
assert selected_total = 2, format('the total must be 2, %s instead', selected_total);
|
assert selected_total = 2, format('the total must be 2, %s instead', selected_total);
|
||||||
|
|
||||||
|
-- get articles by workgroup id
|
||||||
|
select resource, total into selected_article, selected_total from find_articles(_filter => json_build_object('workgroup_id', _workgroup_id));
|
||||||
|
assert selected_article#>>'{0,title}' = 'Love my group', format('title must be "Love my group", %s', selected_article#>>'{0,title}');
|
||||||
|
assert selected_total = 1, format('the total must be 1, %s instead', selected_total);
|
||||||
|
|
||||||
-- get articles versions by id
|
-- get articles versions by id
|
||||||
select resource, total into selected_article, selected_total from find_articles_versions_by_id((created_article->>'id')::uuid);
|
select resource, total into selected_article, selected_total from find_articles_versions_by_id((created_article->>'id')::uuid);
|
||||||
assert selected_article#>>'{0,title}' = 'Love the world', format('title must be "Love the world", %s', selected_article#>>'{0,title}');
|
assert selected_article#>>'{0,title}' = 'Love the world', format('title must be "Love the world", %s', selected_article#>>'{0,title}');
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
create or replace function fixture_workgroup(in name text default 'vert', _citizen_id uuid default fixture_citizen(), out _article_id uuid)
|
create or replace function fixture_workgroup(in name text default 'vert', _citizen_id uuid default fixture_citizen(), out _workgroup_id uuid)
|
||||||
language plpgsql as
|
language plpgsql as
|
||||||
$$
|
$$
|
||||||
declare
|
declare
|
||||||
@@ -23,6 +23,7 @@ begin
|
|||||||
|
|
||||||
-- upsert workgroup
|
-- upsert workgroup
|
||||||
select upsert_workgroup(created_workgroup) into created_workgroup;
|
select upsert_workgroup(created_workgroup) into created_workgroup;
|
||||||
|
select (created_workgroup->>'id')::uuid into _workgroup_id;
|
||||||
assert created_workgroup->>'description' is not null, 'description should not be null';
|
assert created_workgroup->>'description' is not null, 'description should not be null';
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|||||||
Reference in New Issue
Block a user