Fix #106

Open
flecomte wants to merge 2 commits from fix into master
82 changed files with 231 additions and 230 deletions

View File

@@ -48,7 +48,7 @@ data class ArticleForView(
val lastVersion: Boolean = false val lastVersion: Boolean = false
} }
interface ArticleForUpdateI<C : CitizenRef> : ArticleI, ArticleWithTitleI, VersionableId, TargetI, CreatedBy<C> { sealed interface ArticleForUpdateI<C : CitizenRef> : ArticleI, ArticleWithTitleI, VersionableId, TargetI, CreatedBy<C> {
val anonymous: Boolean val anonymous: Boolean
val content: String val content: String
val description: String val description: String
@@ -56,13 +56,13 @@ interface ArticleForUpdateI<C : CitizenRef> : ArticleI, ArticleWithTitleI, Versi
val workgroup: WorkgroupRef? val workgroup: WorkgroupRef?
} }
class ArticleForUpdate( data class ArticleForUpdate(
override val id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
override val title: String, override val title: String,
override val anonymous: Boolean = true, override val anonymous: Boolean = true,
override val content: String, override val content: String,
override val description: String, override val description: String,
tags: List<String> = emptyList(), val tags: Set<String> = emptySet(),
override val draft: Boolean = false, override val draft: Boolean = false,
override val createdBy: CitizenRef, override val createdBy: CitizenRef,
override val workgroup: WorkgroupRef? = null, override val workgroup: WorkgroupRef? = null,
@@ -71,12 +71,10 @@ class ArticleForUpdate(
) : ArticleRef(id), ) : ArticleRef(id),
ArticleForUpdateI<CitizenRef>, ArticleForUpdateI<CitizenRef>,
ArticleAuthI<CitizenRef>, ArticleAuthI<CitizenRef>,
VersionableId { VersionableId
val tags: List<String> = tags.distinct()
}
class ArticleForListing( data class ArticleForListing(
id: UUID? = null, override val id: UUID = UUID.randomUUID(),
override val title: String, override val title: String,
override val createdBy: CitizenCreator, override val createdBy: CitizenCreator,
override val workgroup: WorkgroupCart? = null, override val workgroup: WorkgroupCart? = null,
@@ -90,7 +88,7 @@ class ArticleForListing(
CreatedAt by CreatedAt.Imp(), CreatedAt by CreatedAt.Imp(),
CreatedBy<CitizenCartI> CreatedBy<CitizenCartI>
interface ArticleForListingI : ArticleWithTitleI, CreatedBy<CitizenCartI> { sealed interface ArticleForListingI : ArticleWithTitleI, CreatedBy<CitizenCartI> {
val workgroup: WorkgroupCartI? val workgroup: WorkgroupCartI?
} }
@@ -98,13 +96,13 @@ open class ArticleRef(
id: UUID? = null id: UUID? = null
) : ArticleI, TargetRef(id) ) : ArticleI, TargetRef(id)
interface ArticleI : EntityI, TargetI sealed interface ArticleI : EntityI, TargetI
interface ArticleWithTitleI : ArticleI { sealed interface ArticleWithTitleI : ArticleI {
val title: String val title: String
} }
interface ArticleAuthI<U : CitizenI> : sealed interface ArticleAuthI<U : CitizenI> :
ArticleI, ArticleI,
CreatedBy<U>, CreatedBy<U>,
DeletedAt { DeletedAt {

View File

@@ -65,7 +65,7 @@ object FindArticleVersions {
it.validate().badRequestIfNotValid() it.validate().badRequestIfNotValid()
repo.findVersions(it) repo.findVersions(it)
.apply { ac.assert { canView(result, citizenOrNull) } } .apply { ac.canView(result, citizenOrNull).assert() }
.run { .run {
call.respond( call.respond(
toOutput { a: ArticleForListing -> toOutput { a: ArticleForListing ->

View File

@@ -76,7 +76,7 @@ object FindArticles {
it.validate().badRequestIfNotValid() it.validate().badRequestIfNotValid()
repo.findArticles(it) repo.findArticles(it)
.apply { ac.assert { canView(result, citizenOrNull) } } .apply { ac.canView(result, citizenOrNull).assert() }
.let { .let {
call.respond( call.respond(
it.toOutput { it.toOutput {

View File

@@ -27,7 +27,7 @@ object GetOneArticle {
fun Route.getOneArticle(viewRepository: ArticleViewRepository<ArticleForView>, ac: ArticleAccessControl, repo: ArticleRepository) { fun Route.getOneArticle(viewRepository: ArticleViewRepository<ArticleForView>, ac: ArticleAccessControl, repo: ArticleRepository) {
get<ArticleRequest> { get<ArticleRequest> {
val article: ArticleForView = repo.findById(it.article.id) ?: throw NotFoundException("Article ${it.article.id} not found") val article: ArticleForView = repo.findById(it.article.id) ?: throw NotFoundException("Article ${it.article.id} not found")
ac.assert { canView(article, citizenOrNull) } ac.canView(article, citizenOrNull).assert()
call.respond( call.respond(
article.let { a -> article.let { a ->

View File

@@ -37,7 +37,7 @@ object UpsertArticle {
val anonymous: Boolean = true, val anonymous: Boolean = true,
val content: String, val content: String,
val description: String, val description: String,
val tags: List<String> = emptyList(), val tags: Set<String> = emptySet(),
val draft: Boolean = false, val draft: Boolean = false,
val versionId: UUID, val versionId: UUID,
val workgroup: WorkgroupRef? = null, val workgroup: WorkgroupRef? = null,
@@ -83,7 +83,7 @@ object UpsertArticle {
post<UpsertArticleRequest> { post<UpsertArticleRequest> {
mustBeAuth() mustBeAuth()
val article = call.convertRequestToEntity() val article = call.convertRequestToEntity()
ac.assert { canUpsert(article, citizenOrNull) } ac.canUpsert(article, citizenOrNull).assert()
repo.upsert(article)?.let { a -> repo.upsert(article)?.let { a ->
call.respond( call.respond(
object { object {

View File

@@ -9,35 +9,45 @@ import io.ktor.auth.Principal
import org.joda.time.DateTime import org.joda.time.DateTime
import java.util.UUID import java.util.UUID
class UserForCreate( data class UserForCreate(
id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
username: String, override val username: String,
override val password: String, override val password: String,
blockedAt: DateTime? = null, override val blockedAt: DateTime? = null,
roles: List<Roles> = emptyList() override val roles: Set<Roles> = emptySet()
) : User(id, username, blockedAt, roles), ) : UserForViewI,
UserWithPasswordI UserWithPasswordI,
CreatedAt by CreatedAt.Imp(),
UpdatedAt by UpdatedAt.Imp()
open class User( data class User(
id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
override var username: String, override val username: String,
var blockedAt: DateTime? = null, override val blockedAt: DateTime? = null,
var roles: List<Roles> = emptyList() override val roles: Set<Roles> = emptySet()
) : UserRef(id), ) : UserRef(id),
UserForViewI,
UserWithUsername, UserWithUsername,
CreatedAt by CreatedAt.Imp(), CreatedAt by CreatedAt.Imp(),
UpdatedAt by UpdatedAt.Imp() UpdatedAt by UpdatedAt.Imp()
sealed interface UserForViewI :
UserI,
UserWithUsername,
UserForAuthI,
CreatedAt,
UpdatedAt
class UserCreator( class UserCreator(
id: UUID = UUID.randomUUID(), id: UUID = UUID.randomUUID(),
override val username: String, override val username: String,
) : UserRef(id), UserWithUsername ) : UserRef(id), UserWithUsername
interface UserWithUsername : UserI { sealed interface UserWithUsername : UserI {
val username: String val username: String
} }
interface UserWithPasswordI : UserI { sealed interface UserWithPasswordI : UserI {
val password: String val password: String
} }
@@ -51,11 +61,11 @@ open class UserRef(
id: UUID = UUID.randomUUID() id: UUID = UUID.randomUUID()
) : UserI, Entity(id) ) : UserI, Entity(id)
interface UserI : EntityI, Principal { sealed interface UserI : EntityI, Principal {
enum class Roles { ROLE_USER, ROLE_ADMIN } enum class Roles { ROLE_USER, ROLE_ADMIN }
} }
interface UserForAuthI : UserI { sealed interface UserForAuthI : UserI {
var roles: List<Roles> val roles: Set<Roles>
var blockedAt: DateTime? val blockedAt: DateTime?
} }

View File

@@ -91,7 +91,7 @@ object Register {
user = UserForCreate( user = UserForCreate(
username = user.username, username = user.username,
password = user.password, password = user.password,
roles = listOf(UserI.Roles.ROLE_USER) roles = setOf(UserI.Roles.ROLE_USER)
) )
) )

View File

@@ -17,19 +17,19 @@ import fr.postgresjson.entity.Serializable
import org.joda.time.DateTime import org.joda.time.DateTime
import java.util.UUID import java.util.UUID
class CitizenForCreate( data class CitizenForCreate(
val name: Name, val name: Name,
val email: String, val email: String,
val birthday: DateTime, val birthday: DateTime,
val voteAnonymous: Boolean = true, val voteAnonymous: Boolean = true,
val followAnonymous: Boolean = true, val followAnonymous: Boolean = true,
override val user: UserForCreate, override val user: UserForCreate,
id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
) : CitizenI, ) : CitizenI,
CitizenRefWithUser(id, user), CitizenWithUserI by CitizenRefWithUser(id, user),
CreatedAt by CreatedAt.Imp() CreatedAt by CreatedAt.Imp()
class Citizen( data class Citizen(
override val id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
override val name: Name, override val name: Name,
override val email: String, override val email: String,
@@ -37,7 +37,7 @@ class Citizen(
override val voteAnonymous: Boolean = true, override val voteAnonymous: Boolean = true,
override val followAnonymous: Boolean = true, override val followAnonymous: Boolean = true,
override val user: User, override val user: User,
deletedAt: DateTime? = null override val deletedAt: DateTime? = null
) : CitizenWithEmail, ) : CitizenWithEmail,
CitizenCreatorI, CitizenCreatorI,
CitizenWithUserI, CitizenWithUserI,
@@ -62,10 +62,11 @@ data class CitizenCreator(
override val user: UserCreator, override val user: UserCreator,
override val deletedAt: DateTime? = null override val deletedAt: DateTime? = null
) : CitizenCreatorI, ) : CitizenCreatorI,
CitizenRefWithUser(id, user), CitizenI,
CitizenWithUserI by CitizenRefWithUser(id, user),
DeletedAt by DeletedAt.Imp(deletedAt) DeletedAt by DeletedAt.Imp(deletedAt)
interface CitizenCreatorI : CitizenWithUserI, CitizenWithEmail, CitizenCartI, DeletedAt { sealed interface CitizenCreatorI : CitizenWithUserI, CitizenWithEmail, CitizenCartI, DeletedAt {
override val id: UUID override val id: UUID
override val name: Name override val name: Name
override val email: String override val email: String
@@ -75,8 +76,8 @@ interface CitizenCreatorI : CitizenWithUserI, CitizenWithEmail, CitizenCartI, De
override val deletedAt: DateTime? override val deletedAt: DateTime?
} }
class CitizenCart( data class CitizenCart(
id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
override val name: Name, override val name: Name,
override val user: UserRef, override val user: UserRef,
override val deletedAt: DateTime? = null, override val deletedAt: DateTime? = null,
@@ -84,13 +85,13 @@ class CitizenCart(
CitizenCartI, CitizenCartI,
DeletedAt by DeletedAt.Imp(deletedAt) DeletedAt by DeletedAt.Imp(deletedAt)
interface CitizenCartI : CitizenI, CitizenWithUserI { sealed interface CitizenCartI : CitizenI, CitizenWithUserI {
val name: Name val name: Name
} }
open class CitizenRefWithUser( data class CitizenRefWithUser(
id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
override val user: UserRef override val user: UserI
) : CitizenWithUserI, ) : CitizenWithUserI,
CitizenRef(id) CitizenRef(id)
@@ -99,7 +100,7 @@ open class CitizenRef(
) : TargetRef(id), ) : TargetRef(id),
CitizenI CitizenI
interface CitizenI : EntityI, TargetI { sealed interface CitizenI : EntityI, TargetI {
data class Name( data class Name(
override val firstName: String, override val firstName: String,
override val lastName: String, override val lastName: String,
@@ -114,10 +115,10 @@ interface CitizenI : EntityI, TargetI {
} }
} }
interface CitizenWithUserI : CitizenI { sealed interface CitizenWithUserI : CitizenI {
val user: UserI val user: UserI
} }
interface CitizenWithEmail : CitizenI { sealed interface CitizenWithEmail : CitizenI {
val email: String val email: String
} }

View File

@@ -42,7 +42,7 @@ object ChangeMyPassword {
mustBeAuth() mustBeAuth()
val content = call.receiveOrBadRequest<ChangePasswordCitizenRequest.Input>() val content = call.receiveOrBadRequest<ChangePasswordCitizenRequest.Input>()
.apply { validate().badRequestIfNotValid() } .apply { validate().badRequestIfNotValid() }
ac.assert { canChangePassword(it.citizen, citizenOrNull) } ac.canChangePassword(it.citizen, citizenOrNull).assert()
userRepository.findByCredentials(UserPasswordCredential(citizen.user.username, content.oldPassword)) ?: throw BadRequestException("Bad Password") userRepository.findByCredentials(UserPasswordCredential(citizen.user.username, content.oldPassword)) ?: throw BadRequestException("Bad Password")
userRepository.changePassword( userRepository.changePassword(
UserWithPassword( UserWithPassword(

View File

@@ -55,7 +55,7 @@ object FindCitizens {
mustBeAuth() mustBeAuth()
it.validate().badRequestIfNotValid() it.validate().badRequestIfNotValid()
val citizens = repo.find(it.page, it.limit, it.sort, it.direction, it.search) val citizens = repo.find(it.page, it.limit, it.sort, it.direction, it.search)
ac.assert { canView(citizens.result, citizenOrNull) } ac.canView(citizens.result, citizenOrNull).assert()
call.respond( call.respond(
citizens.toOutput { c: CitizenCreator -> citizens.toOutput { c: CitizenCreator ->
object { object {

View File

@@ -28,7 +28,7 @@ object GetCurrentCitizen {
if (currentUser === null) { if (currentUser === null) {
call.respond(HttpStatusCode.Unauthorized) call.respond(HttpStatusCode.Unauthorized)
} else { } else {
ac.assert { canView(currentUser, citizenOrNull) } ac.canView(currentUser, citizenOrNull).assert()
call.respond( call.respond(
object { object {
val id: UUID = citizen.id val id: UUID = citizen.id

View File

@@ -29,7 +29,7 @@ object GetOneCitizen {
get<CitizenRequest> { get<CitizenRequest> {
mustBeAuth() mustBeAuth()
val citizen = citizenRepository.findById(it.citizen.id) ?: throw NotFoundException("Citizen not found ${it.citizen.id}") val citizen = citizenRepository.findById(it.citizen.id) ?: throw NotFoundException("Citizen not found ${it.citizen.id}")
ac.assert { canView(citizen, citizenOrNull) } ac.canView(citizen, citizenOrNull).assert()
call.respond( call.respond(
object { object {

View File

@@ -51,7 +51,7 @@ object CreateCommentArticle {
content = content content = content
) )
}.let { comment -> }.let { comment ->
ac.assert { canCreate(comment, citizenOrNull) } ac.canCreate(comment, citizenOrNull).assert()
repo.comment(comment) repo.comment(comment)
call.respond( call.respond(

View File

@@ -58,7 +58,7 @@ object GetArticleComments {
val comments = repo.findByTarget(it.article, it.page, it.limit, it.sort) val comments = repo.findByTarget(it.article, it.page, it.limit, it.sort)
if (comments.result.isNotEmpty()) { if (comments.result.isNotEmpty()) {
ac.assert { canView(comments.result, citizenOrNull) } ac.canView(comments.result, citizenOrNull).assert()
} }
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,

View File

@@ -28,7 +28,7 @@ object GetCitizenArticleComments {
get<CitizenCommentArticleRequest> { get<CitizenCommentArticleRequest> {
mustBeAuth() mustBeAuth()
repo.findByCitizen(it.citizen).let { comments -> repo.findByCitizen(it.citizen).let { comments ->
ac.assert { canView(comments.result, citizenOrNull) } ac.canView(comments.result, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
comments.toOutput { comment -> comments.toOutput { comment ->

View File

@@ -53,7 +53,7 @@ object CreateConstitutionComment {
content = content content = content
) )
}.let { comment -> }.let { comment ->
ac.assert { canCreate(comment, citizenOrNull) } ac.canCreate(comment, citizenOrNull).assert()
repo.comment(comment) repo.comment(comment)
call.respond( call.respond(

View File

@@ -28,7 +28,7 @@ object GetCitizenCommentConstitution {
get<GetCitizenCommentConstitutionRequest> { get<GetCitizenCommentConstitutionRequest> {
mustBeAuth() mustBeAuth()
val comments = repo.findByCitizen(it.citizen) val comments = repo.findByCitizen(it.citizen)
ac.assert { canView(comments.result, citizenOrNull) } ac.canView(comments.result, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
comments.toOutput { comment -> comments.toOutput { comment ->

View File

@@ -57,7 +57,7 @@ object GetConstitutionComment {
it.validate().badRequestIfNotValid() it.validate().badRequestIfNotValid()
val comments = repo.findByTarget(it.constitution) val comments = repo.findByTarget(it.constitution)
ac.assert { canView(comments.result, citizenOrNull) } ac.canView(comments.result, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
comments.toOutput { comment -> comments.toOutput { comment ->

View File

@@ -16,8 +16,8 @@ import fr.dcproject.component.vote.entity.VotableImp
import org.joda.time.DateTime import org.joda.time.DateTime
import java.util.UUID import java.util.UUID
class CommentForView<T : TargetI, C : CitizenCreatorI>( data class CommentForView<T : TargetI, C : CitizenCreatorI>(
id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
override val createdBy: C, override val createdBy: C,
override val target: T, override val target: T,
override var content: String, override var content: String,
@@ -30,7 +30,7 @@ class CommentForView<T : TargetI, C : CitizenCreatorI>(
CommentWithTargetI<T>, CommentWithTargetI<T>,
CreatedBy<C> by CreatedBy.Imp(createdBy), CreatedBy<C> by CreatedBy.Imp(createdBy),
UpdatedAt by UpdatedAt.Imp(), UpdatedAt by UpdatedAt.Imp(),
DeletedAt by DeletedAt.Imp(), DeletedAt,
Votable by VotableImp(), Votable by VotableImp(),
TargetI { TargetI {
constructor( constructor(
@@ -50,9 +50,9 @@ open class CommentForUpdate<T : TargetI, C : CitizenI>(
override val createdBy: C, override val createdBy: C,
override val target: T, override val target: T,
open var content: String, open var content: String,
override val parent: CommentParent<T>? = null, override val parent: CommentParentI<T>? = null,
override val deletedAt: DateTime? = null override val deletedAt: DateTime? = null
) : CommentParent<T>(id, deletedAt, target), ) : CommentParentI<T> by CommentParent(id, deletedAt, target),
CommentWithParentI<T>, CommentWithParentI<T>,
ExtraI<T, C>, ExtraI<T, C>,
CommentWithTargetI<T>, CommentWithTargetI<T>,
@@ -62,7 +62,7 @@ open class CommentForUpdate<T : TargetI, C : CitizenI>(
TargetI { TargetI {
constructor( constructor(
createdBy: C, createdBy: C,
parent: CommentParent<T>, parent: CommentParentI<T>,
content: String, content: String,
id: UUID? = null, id: UUID? = null,
) : this( ) : this(
@@ -74,21 +74,21 @@ open class CommentForUpdate<T : TargetI, C : CitizenI>(
) )
} }
open class CommentParent<T : TargetI>( data class CommentParent<T : TargetI>(
override val id: UUID, override val id: UUID,
override val deletedAt: DateTime?, override val deletedAt: DateTime?,
override val target: T override val target: T
) : CommentRef(id), ) : CommentRef(id),
CommentParentI<T> CommentParentI<T>
interface CommentParentI<T : TargetI> : CommentI, DeletedAt, CommentWithTargetI<T> sealed interface CommentParentI<T : TargetI> : CommentI, DeletedAt, CommentWithTargetI<T>
interface CommentWithTargetI<T : TargetI> : CommentI, TargetI, HasTarget<T> interface CommentWithTargetI<T : TargetI> : CommentI, TargetI, HasTarget<T>
interface CommentWithParentI<T : TargetI> { interface CommentWithParentI<T : TargetI> {
val parent: CommentParent<T>? val parent: CommentParentI<T>?
} }
open class CommentRef(id: UUID = UUID.randomUUID()) : CommentI, TargetRef(id) open class CommentRef(id: UUID = UUID.randomUUID()) : CommentI, TargetRef(id)
interface CommentI : EntityI sealed interface CommentI : EntityI

View File

@@ -32,26 +32,21 @@ abstract class CommentRepositoryAbs<T : TargetI>(override var requester: Request
parentId: UUID, parentId: UUID,
page: Int = 1, page: Int = 1,
limit: Int = 50 limit: Int = 50
): Paginated<CommentForView<T, CitizenCreatorI>> { ): Paginated<CommentForView<T, CitizenCreatorI>> = requester
return requester.run { .getFunction("find_comments_by_parent")
getFunction("find_comments_by_parent")
.select<CommentForView<T, CitizenCreator>>( .select<CommentForView<T, CitizenCreator>>(
page, page,
limit, limit,
"parent_id" to parentId "parent_id" to parentId
) )
as Paginated<CommentForView<T, CitizenCreatorI>> as Paginated<CommentForView<T, CitizenCreatorI>>
}
}
open fun findByTarget( open fun findByTarget(
target: EntityI, target: EntityI,
page: Int = 1, page: Int = 1,
limit: Int = 50, limit: Int = 50,
sort: String = "createdAt" sort: String = "createdAt"
): Paginated<CommentForView<T, CitizenCreatorI>> { ): Paginated<CommentForView<T, CitizenCreatorI>> = findByTarget(target.id, page, limit, sort)
return findByTarget(target.id, page, limit, sort)
}
open fun findByTarget( open fun findByTarget(
targetId: UUID, targetId: UUID,
@@ -85,35 +80,29 @@ abstract class CommentRepositoryAbs<T : TargetI>(override var requester: Request
} }
class CommentRepository(requester: Requester) : CommentRepositoryAbs<TargetRef>(requester) { class CommentRepository(requester: Requester) : CommentRepositoryAbs<TargetRef>(requester) {
override fun findById(id: UUID): CommentForView<TargetRef, CitizenCreatorI>? { override fun findById(id: UUID): CommentForView<TargetRef, CitizenCreatorI>? = requester
return requester
.getFunction("find_comment_by_id") .getFunction("find_comment_by_id")
.selectOne<CommentForView<TargetRef, CitizenCreator>>(mapOf("id" to id)) .selectOne<CommentForView<TargetRef, CitizenCreator>>(mapOf("id" to id))
as CommentForView<TargetRef, CitizenCreatorI>? as CommentForView<TargetRef, CitizenCreatorI>?
}
override fun findByCitizen( override fun findByCitizen(
citizen: CitizenI, citizen: CitizenI,
page: Int, page: Int,
limit: Int limit: Int
): Paginated<CommentForView<TargetRef, CitizenCreatorI>> { ): Paginated<CommentForView<TargetRef, CitizenCreatorI>> = requester
return requester.run { .getFunction("find_comments_by_citizen")
getFunction("find_comments_by_citizen")
.select<CommentForView<TargetRef, CitizenCreator>>( .select<CommentForView<TargetRef, CitizenCreator>>(
page, page,
limit, limit,
"created_by_id" to citizen.id "created_by_id" to citizen.id
) as Paginated<CommentForView<TargetRef, CitizenCreatorI>> ) as Paginated<CommentForView<TargetRef, CitizenCreatorI>>
}
}
override fun findByParent( override fun findByParent(
parentId: UUID, parentId: UUID,
page: Int, page: Int,
limit: Int limit: Int
): Paginated<CommentForView<TargetRef, CitizenCreatorI>> { ): Paginated<CommentForView<TargetRef, CitizenCreatorI>> = requester
return requester.run { .getFunction("find_comments_by_parent")
getFunction("find_comments_by_parent")
.select<CommentForView<TargetRef, CitizenCreator>>( .select<CommentForView<TargetRef, CitizenCreator>>(
page, page,
limit, limit,
@@ -121,5 +110,3 @@ class CommentRepository(requester: Requester) : CommentRepositoryAbs<TargetRef>(
) )
as Paginated<CommentForView<TargetRef, CitizenCreatorI>> as Paginated<CommentForView<TargetRef, CitizenCreatorI>>
} }
}
}

View File

@@ -54,7 +54,7 @@ object CreateComment {
parent = parent, parent = parent,
) )
}.let { newComment -> }.let { newComment ->
ac.assert { canCreate(newComment, citizenOrNull) } ac.canCreate(newComment, citizenOrNull).assert()
repo.comment(newComment) repo.comment(newComment)
call.respond(HttpStatusCode.Created, newComment.toOutput()) call.respond(HttpStatusCode.Created, newComment.toOutput())
} }

View File

@@ -42,7 +42,7 @@ object EditComment {
put<EditCommentRequest> { put<EditCommentRequest> {
mustBeAuth() mustBeAuth()
val commentOld = repo.findById(it.comment.id) ?: throw NotFoundException("Comment not found") val commentOld = repo.findById(it.comment.id) ?: throw NotFoundException("Comment not found")
ac.assert { canUpdate(commentOld, citizenOrNull) } ac.canUpdate(commentOld, citizenOrNull).assert()
call.receiveOrBadRequest<EditCommentRequest.Input>() call.receiveOrBadRequest<EditCommentRequest.Input>()
.apply { validate().badRequestIfNotValid() } .apply { validate().badRequestIfNotValid() }

View File

@@ -39,7 +39,7 @@ object GetCommentChildren {
it.limit it.limit
) )
ac.assert { canView(comments.result, citizenOrNull) } ac.canView(comments.result, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,

View File

@@ -27,7 +27,7 @@ object GetOneComment {
fun Route.getOneComment(repo: CommentRepository, ac: CommentAccessControl) { fun Route.getOneComment(repo: CommentRepository, ac: CommentAccessControl) {
get<CommentRequest> { get<CommentRequest> {
val comment = repo.findById(it.comment.id) ?: throw NotFoundException("Comment ${it.comment.id} not found") val comment = repo.findById(it.comment.id) ?: throw NotFoundException("Comment ${it.comment.id} not found")
ac.assert { canView(comment, citizenOrNull) } ac.canView(comment, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,

View File

@@ -89,7 +89,7 @@ object CreateConstitution {
post<PostConstitutionRequest> { post<PostConstitutionRequest> {
mustBeAuth() mustBeAuth()
getNewConstitution(call.receiveOrBadRequest(), citizen).let { getNewConstitution(call.receiveOrBadRequest(), citizen).let {
ac.assert { canCreate(it, citizenOrNull) } ac.canCreate(it, citizenOrNull).assert()
val c = repo.upsert(it) ?: error("Unable to create Constitution") val c = repo.upsert(it) ?: error("Unable to create Constitution")
call.respond( call.respond(
HttpStatusCode.Created, HttpStatusCode.Created,

View File

@@ -54,7 +54,7 @@ object FindConstitutions {
get<FindConstitutionsRequest> { get<FindConstitutionsRequest> {
it.validate().badRequestIfNotValid() it.validate().badRequestIfNotValid()
val constitutions = repo.find(it.page, it.limit, it.sort, it.direction, it.search) val constitutions = repo.find(it.page, it.limit, it.sort, it.direction, it.search)
ac.assert { canView(constitutions.result, citizenOrNull) } ac.canView(constitutions.result, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
constitutions.toOutput { c -> constitutions.toOutput { c ->

View File

@@ -27,7 +27,7 @@ object GetConstitution {
fun Route.getConstitution(ac: ConstitutionAccessControl, constitutionRepo: ConstitutionRepository) { fun Route.getConstitution(ac: ConstitutionAccessControl, constitutionRepo: ConstitutionRepository) {
get<GetConstitutionRequest> { get<GetConstitutionRequest> {
val constitution = constitutionRepo.findById(it.constitution.id) ?: throw NotFoundException("Unable to find constitution ${it.constitution.id}") val constitution = constitutionRepo.findById(it.constitution.id) ?: throw NotFoundException("Unable to find constitution ${it.constitution.id}")
ac.assert { canView(constitution, citizenOrNull) } ac.canView(constitution, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
constitution.let { c -> constitution.let { c ->

View File

@@ -8,19 +8,18 @@ import fr.dcproject.common.entity.HasTarget
import fr.dcproject.common.entity.TargetI import fr.dcproject.common.entity.TargetI
import fr.dcproject.component.citizen.database.CitizenCreator import fr.dcproject.component.citizen.database.CitizenCreator
import fr.dcproject.component.citizen.database.CitizenI import fr.dcproject.component.citizen.database.CitizenI
import fr.dcproject.component.citizen.database.CitizenRef
import java.util.UUID import java.util.UUID
open class FollowForView<T : TargetI>( data class FollowForView<T : TargetI>(
id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
override val createdBy: CitizenCreator, override val createdBy: CitizenCreator,
override var target: T override var target: T
) : ExtraI<T, CitizenRef>, ) : ExtraI<T, CitizenI>,
FollowRef(id), FollowRef(id),
Created<CitizenRef> by Created.Imp(createdBy) Created<CitizenI> by Created.Imp(createdBy)
class FollowForUpdate<T : TargetI, C : CitizenI>( data class FollowForUpdate<T : TargetI, C : CitizenI>(
id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
override val target: T, override val target: T,
override val createdBy: C override val createdBy: C
) : FollowRef(id), ) : FollowRef(id),
@@ -31,4 +30,4 @@ open class FollowRef(
override val id: UUID override val id: UUID
) : FollowI ) : FollowI
interface FollowI : EntityI sealed interface FollowI : EntityI

View File

@@ -28,7 +28,7 @@ object FollowArticle {
post<ArticleFollowRequest> { post<ArticleFollowRequest> {
mustBeAuth() mustBeAuth()
val follow = FollowForUpdate(target = it.article, createdBy = this.citizen) val follow = FollowForUpdate(target = it.article, createdBy = this.citizen)
ac.assert { canCreate(follow, citizenOrNull) } ac.canCreate(follow, citizenOrNull).assert()
repo.follow(follow) repo.follow(follow)
call.respond(HttpStatusCode.Created) call.respond(HttpStatusCode.Created)
} }

View File

@@ -27,7 +27,7 @@ object GetFollowArticle {
fun Route.getFollowArticle(repo: FollowArticleRepository, ac: FollowAccessControl) { fun Route.getFollowArticle(repo: FollowArticleRepository, ac: FollowAccessControl) {
get<ArticleFollowRequest> { get<ArticleFollowRequest> {
repo.findFollow(citizen, it.article)?.let { follow -> repo.findFollow(citizen, it.article)?.let { follow ->
ac.assert { canView(follow, citizenOrNull) } ac.canView(follow, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
follow.toOutput() follow.toOutput()

View File

@@ -28,7 +28,7 @@ object GetMyFollowsArticle {
get<CitizenFollowArticleRequest> { get<CitizenFollowArticleRequest> {
mustBeAuth() mustBeAuth()
val follows = repo.findByCitizen(it.citizen) val follows = repo.findByCitizen(it.citizen)
ac.assert { canView(follows.result, citizenOrNull) } ac.canView(follows.result, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
follows.toOutput { f -> follows.toOutput { f ->

View File

@@ -28,7 +28,7 @@ object UnfollowArticle {
delete<ArticleFollowRequest> { delete<ArticleFollowRequest> {
mustBeAuth() mustBeAuth()
val follow = FollowForUpdate(target = it.article, createdBy = this.citizen) val follow = FollowForUpdate(target = it.article, createdBy = this.citizen)
ac.assert { canDelete(follow, citizenOrNull) } ac.canDelete(follow, citizenOrNull).assert()
repo.unfollow(follow) repo.unfollow(follow)
call.respond(HttpStatusCode.NoContent) call.respond(HttpStatusCode.NoContent)
} }

View File

@@ -28,7 +28,7 @@ object FollowCitizen {
post<CitizenFollowRequest> { post<CitizenFollowRequest> {
mustBeAuth() mustBeAuth()
val follow = FollowForUpdate(target = it.citizen, createdBy = this.citizen) val follow = FollowForUpdate(target = it.citizen, createdBy = this.citizen)
ac.assert { canCreate(follow, citizenOrNull) } ac.canCreate(follow, citizenOrNull).assert()
repo.follow(follow) repo.follow(follow)
call.respond(HttpStatusCode.Created) call.respond(HttpStatusCode.Created)
} }

View File

@@ -26,7 +26,7 @@ object GetFollowCitizen {
fun Route.getFollowCitizen(repo: FollowCitizenRepository, ac: FollowAccessControl) { fun Route.getFollowCitizen(repo: FollowCitizenRepository, ac: FollowAccessControl) {
get<CitizenFollowRequest> { get<CitizenFollowRequest> {
repo.findFollow(citizen, it.citizen)?.let { follow -> repo.findFollow(citizen, it.citizen)?.let { follow ->
ac.assert { canView(follow, citizenOrNull) } ac.canView(follow, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
follow.toOutput() follow.toOutput()

View File

@@ -28,7 +28,7 @@ object GetMyFollowsCitizen {
get<CitizenFollowCitizenRequest> { get<CitizenFollowCitizenRequest> {
mustBeAuth() mustBeAuth()
val follows = repo.findByCitizen(it.citizen) val follows = repo.findByCitizen(it.citizen)
ac.assert { canView(follows.result, citizenOrNull) } ac.canView(follows.result, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
follows.toOutput { f -> follows.toOutput { f ->

View File

@@ -28,7 +28,7 @@ object UnfollowCitizen {
delete<CitizenFollowRequest> { delete<CitizenFollowRequest> {
mustBeAuth() mustBeAuth()
val follow = FollowForUpdate(target = it.citizen, createdBy = this.citizen) val follow = FollowForUpdate(target = it.citizen, createdBy = this.citizen)
ac.assert { canDelete(follow, citizenOrNull) } ac.canDelete(follow, citizenOrNull).assert()
repo.unfollow(follow) repo.unfollow(follow)
call.respond(HttpStatusCode.NoContent) call.respond(HttpStatusCode.NoContent)
} }

View File

@@ -28,7 +28,7 @@ object FollowConstitution {
post<ConstitutionFollowRequest> { post<ConstitutionFollowRequest> {
mustBeAuth() mustBeAuth()
val follow = FollowForUpdate(target = it.constitution, createdBy = this.citizen) val follow = FollowForUpdate(target = it.constitution, createdBy = this.citizen)
ac.assert { canCreate(follow, citizenOrNull) } ac.canCreate(follow, citizenOrNull).assert()
repo.follow(follow) repo.follow(follow)
call.respond(HttpStatusCode.Created) call.respond(HttpStatusCode.Created)
} }

View File

@@ -27,7 +27,7 @@ object GetFollowConstitution {
fun Route.getFollowConstitution(repo: FollowConstitutionRepository, ac: FollowAccessControl) { fun Route.getFollowConstitution(repo: FollowConstitutionRepository, ac: FollowAccessControl) {
get<ConstitutionFollowRequest> { get<ConstitutionFollowRequest> {
repo.findFollow(citizen, it.constitution)?.let { follow -> repo.findFollow(citizen, it.constitution)?.let { follow ->
ac.assert { canView(follow, citizenOrNull) } ac.canView(follow, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
follow.toOutput() follow.toOutput()

View File

@@ -28,7 +28,7 @@ object GetMyFollowsConstitution {
get<CitizenFollowConstitutionRequest> { get<CitizenFollowConstitutionRequest> {
mustBeAuth() mustBeAuth()
val follows = repo.findByCitizen(it.citizen) val follows = repo.findByCitizen(it.citizen)
ac.assert { canView(follows.result, citizenOrNull) } ac.canView(follows.result, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
follows.toOutput { f -> follows.toOutput { f ->

View File

@@ -28,7 +28,7 @@ object UnfollowConstitution {
delete<ConstitutionUnfollowRequest> { delete<ConstitutionUnfollowRequest> {
mustBeAuth() mustBeAuth()
val follow = FollowForUpdate(target = it.constitution, createdBy = this.citizen) val follow = FollowForUpdate(target = it.constitution, createdBy = this.citizen)
ac.assert { canDelete(follow, citizenOrNull) } ac.canDelete(follow, citizenOrNull).assert()
repo.unfollow(follow) repo.unfollow(follow)
call.respond(HttpStatusCode.NoContent) call.respond(HttpStatusCode.NoContent)
} }

View File

@@ -53,11 +53,11 @@ open class NotificationMessage(
} }
open class EntityNotificationMessage <E : Entity> ( open class EntityNotificationMessage <E : Entity> (
val target: E, open val target: E,
type: String, type: String,
val action: String val action: String
) : NotificationMessage(type) ) : NotificationMessage(type)
class ArticleUpdateNotificationMessage( data class ArticleUpdateNotificationMessage(
target: ArticleForView override val target: ArticleForView
) : EntityNotificationMessage<ArticleForView>(target, "article", "update") ) : EntityNotificationMessage<ArticleForView>(target, "article", "update")

View File

@@ -3,7 +3,7 @@ package fr.dcproject.component.notification.email.content
import fr.dcproject.component.article.database.ArticleWithTitleI import fr.dcproject.component.article.database.ArticleWithTitleI
import fr.dcproject.component.citizen.database.Citizen import fr.dcproject.component.citizen.database.Citizen
class ArticleNotificationEmailContent( data class ArticleNotificationEmailContent(
private val citizen: Citizen, private val citizen: Citizen,
private val target: ArticleWithTitleI, private val target: ArticleWithTitleI,
private val domain: String, private val domain: String,

View File

@@ -2,7 +2,7 @@ package fr.dcproject.component.notification.email.content
import fr.dcproject.component.citizen.database.Citizen import fr.dcproject.component.citizen.database.Citizen
class CitizenNotificationEmailContent( data class CitizenNotificationEmailContent(
private val citizen: Citizen, private val citizen: Citizen,
private val target: Citizen, private val target: Citizen,
private val domain: String, private val domain: String,

View File

@@ -13,8 +13,8 @@ import fr.dcproject.component.citizen.database.CitizenI
import fr.dcproject.component.citizen.database.CitizenRef import fr.dcproject.component.citizen.database.CitizenRef
import java.util.UUID import java.util.UUID
open class Opinion<T : TargetI>( data class Opinion<T : TargetI>(
id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
override val createdBy: CitizenCreator, override val createdBy: CitizenCreator,
override val target: T, override val target: T,
val choice: OpinionChoice val choice: OpinionChoice
@@ -39,4 +39,4 @@ open class OpinionRef(
override val id: UUID override val id: UUID
) : OpinionI, TargetRef(id) ) : OpinionI, TargetRef(id)
interface OpinionI : EntityI sealed interface OpinionI : EntityI

View File

@@ -7,6 +7,4 @@ interface Opinionable {
val opinions: Opinions val opinions: Opinions
} }
class OpinionableImp : Opinionable { data class OpinionableImp(override var opinions: OpinionsMutable = mutableMapOf()) : Opinionable
override var opinions: OpinionsMutable = mutableMapOf()
}

View File

@@ -34,7 +34,7 @@ object GetCitizenOpinions {
get<CitizenOpinions> { get<CitizenOpinions> {
mustBeAuth() mustBeAuth()
val opinionsEntities: List<Opinion<ArticleRef>> = repo.findCitizenOpinionsByTargets(it.citizen, it.id) val opinionsEntities: List<Opinion<ArticleRef>> = repo.findCitizenOpinionsByTargets(it.citizen, it.id)
ac.assert { canView(opinionsEntities, citizenOrNull) } ac.canView(opinionsEntities, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,

View File

@@ -55,7 +55,7 @@ object GetMyOpinionsArticle {
it.validate().badRequestIfNotValid() it.validate().badRequestIfNotValid()
val opinions: Paginated<Opinion<TargetRef>> = repo.findCitizenOpinions(citizen, it.page, it.limit) val opinions: Paginated<Opinion<TargetRef>> = repo.findCitizenOpinions(citizen, it.page, it.limit)
ac.assert { canView(opinions.result, citizenOrNull) } ac.canView(opinions.result, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
opinions.toOutput { it.toOutput() } opinions.toOutput { it.toOutput() }

View File

@@ -25,7 +25,7 @@ object GetOpinionChoice {
fun Route.getOpinionChoice(ac: OpinionChoiceAccessControl, opinionChoiceRepository: OpinionChoiceRepository) { fun Route.getOpinionChoice(ac: OpinionChoiceAccessControl, opinionChoiceRepository: OpinionChoiceRepository) {
get<OpinionChoiceRequest> { get<OpinionChoiceRequest> {
val opinionChoice = opinionChoiceRepository.findOpinionChoiceById(it.opinionChoice.id) ?: throw NotFoundException("OpinionChoice ${it.opinionChoice.id} not found") val opinionChoice = opinionChoiceRepository.findOpinionChoiceById(it.opinionChoice.id) ?: throw NotFoundException("OpinionChoice ${it.opinionChoice.id} not found")
ac.assert { canView(it.opinionChoice, citizenOrNull) } ac.canView(it.opinionChoice, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,

View File

@@ -20,7 +20,7 @@ object GetOpinionChoices {
fun Route.getOpinionChoices(repo: OpinionChoiceRepository, ac: OpinionChoiceAccessControl) { fun Route.getOpinionChoices(repo: OpinionChoiceRepository, ac: OpinionChoiceAccessControl) {
get<OpinionChoicesRequest> { get<OpinionChoicesRequest> {
val opinionChoices = repo.findOpinionsChoices(it.targets) val opinionChoices = repo.findOpinionsChoices(it.targets)
ac.assert { canView(opinionChoices, citizenOrNull) } ac.canView(opinionChoices, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,

View File

@@ -43,7 +43,7 @@ object OpinionArticle {
createdBy = citizen createdBy = citizen
) )
}.let { opinions -> }.let { opinions ->
ac.assert { canCreate(opinions, citizenOrNull) } ac.canCreate(opinions, citizenOrNull).assert()
repo.updateOpinions(opinions) repo.updateOpinions(opinions)
}.let { }.let {
call.respond( call.respond(

View File

@@ -2,7 +2,7 @@ package fr.dcproject.component.views.dto
import fr.dcproject.component.views.entity.ViewAggregation import fr.dcproject.component.views.entity.ViewAggregation
class ViewAggregation( data class ViewAggregation(
val total: Int, val total: Int,
val unique: Int val unique: Int
) { ) {

View File

@@ -3,7 +3,7 @@ package fr.dcproject.component.views.entity
import fr.dcproject.common.entity.UpdatedAt import fr.dcproject.common.entity.UpdatedAt
import fr.postgresjson.entity.EntityI import fr.postgresjson.entity.EntityI
class ViewAggregation( data class ViewAggregation(
val total: Int, val total: Int,
val unique: Int val unique: Int
) : EntityI, ) : EntityI,

View File

@@ -12,8 +12,8 @@ import fr.dcproject.component.citizen.database.CitizenCreatorI
import fr.dcproject.component.citizen.database.CitizenI import fr.dcproject.component.citizen.database.CitizenI
import java.util.UUID import java.util.UUID
class VoteForView<T : TargetI>( data class VoteForView<T : TargetI>(
id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
override val createdBy: CitizenCreator, override val createdBy: CitizenCreator,
override val target: T, override val target: T,
val note: Int, val note: Int,
@@ -30,7 +30,7 @@ class VoteForView<T : TargetI>(
} }
} }
class VoteForUpdate<T : TargetI, C : CitizenI>( data class VoteForUpdate<T : TargetI, C : CitizenI>(
override val id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
override val note: Int, override val note: Int,
override val target: T, override val target: T,

View File

@@ -2,10 +2,18 @@ package fr.dcproject.component.vote.dto
import fr.dcproject.component.vote.entity.Votable import fr.dcproject.component.vote.entity.Votable
class VoteAggregation(parent: Votable) { data class VoteAggregation(
val up: Int = parent.votes.up val up: Int,
val neutral: Int = parent.votes.neutral val neutral: Int,
val down: Int = parent.votes.down val down: Int,
val total: Int = parent.votes.total val total: Int,
val score: Int = parent.votes.score val score: Int
) {
constructor(parent: Votable) : this(
up = parent.votes.up,
neutral = parent.votes.neutral,
down = parent.votes.down,
total = parent.votes.total,
score = parent.votes.score
)
} }

View File

@@ -4,6 +4,6 @@ interface Votable {
val votes: VoteAggregation val votes: VoteAggregation
} }
class VotableImp : Votable { data class VotableImp(
override val votes: VoteAggregation = VoteAggregation() override val votes: VoteAggregation = VoteAggregation()
} ) : Votable

View File

@@ -30,7 +30,7 @@ object GetCitizenVotes {
mustBeAuth() mustBeAuth()
val votes = repo.findCitizenVotesByTargets(it.citizen, it.id) val votes = repo.findCitizenVotesByTargets(it.citizen, it.id)
if (votes.isNotEmpty()) { if (votes.isNotEmpty()) {
ac.assert { canView(votes, citizenOrNull) } ac.canView(votes, citizenOrNull).assert()
} }
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,

View File

@@ -49,7 +49,7 @@ object GetCitizenVotesOnArticle {
it.validate().badRequestIfNotValid() it.validate().badRequestIfNotValid()
val votes = repo.findByCitizen(it.citizen, it.page, it.limit) val votes = repo.findByCitizen(it.citizen, it.page, it.limit)
ac.assert { canView(votes.result, citizenOrNull) } ac.canView(votes.result, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,

View File

@@ -51,7 +51,7 @@ object PutVoteOnArticle {
note = input.note, note = input.note,
createdBy = this.citizen createdBy = this.citizen
) )
ac.assert { canCreate(vote, citizenOrNull) } ac.canCreate(vote, citizenOrNull).assert()
val votes = repo.vote(vote) val votes = repo.vote(vote)
call.respond( call.respond(
HttpStatusCode.Created, HttpStatusCode.Created,

View File

@@ -52,7 +52,7 @@ object PutVoteOnComment {
note = input.note, note = input.note,
createdBy = this.citizen createdBy = this.citizen
) )
ac.assert { canCreate(vote, citizenOrNull) } ac.canCreate(vote, citizenOrNull).assert()
val votes = voteCommentRepo.vote(vote) val votes = voteCommentRepo.vote(vote)
call.respond( call.respond(
HttpStatusCode.Created, HttpStatusCode.Created,

View File

@@ -51,7 +51,7 @@ object PutVoteOnConstitution {
note = input.note, note = input.note,
createdBy = this.citizen createdBy = this.citizen
) )
ac.assert { canCreate(vote, citizenOrNull) } ac.canCreate(vote, citizenOrNull).assert()
repo.vote(vote) repo.vote(vote)
call.respond(HttpStatusCode.Created) call.respond(HttpStatusCode.Created)
} }

View File

@@ -43,17 +43,17 @@ data class WorkgroupForUpdate<C : CitizenWithUserI>(
WorkgroupForUpdateI<C>, WorkgroupForUpdateI<C>,
CreatedBy<C> by CreatedBy.Imp(createdBy) CreatedBy<C> by CreatedBy.Imp(createdBy)
interface WorkgroupForUpdateI<C : CitizenWithUserI> : WorkgroupWithAuthI<C>, WorkgroupCartI, CreatedBy<C> { sealed interface WorkgroupForUpdateI<C : CitizenWithUserI> : WorkgroupWithAuthI<C>, WorkgroupCartI, CreatedBy<C> {
val description: String val description: String
val logo: String? val logo: String?
} }
class WorkgroupCart( data class WorkgroupCart(
override val id: UUID, override val id: UUID,
override val name: String override val name: String
) : WorkgroupCartI ) : WorkgroupCartI
interface WorkgroupCartI : EntityI { sealed interface WorkgroupCartI : EntityI {
val name: String val name: String
} }
@@ -61,7 +61,7 @@ open class WorkgroupRef(
id: UUID? = null id: UUID? = null
) : Entity(id ?: UUID.randomUUID()), WorkgroupI ) : Entity(id ?: UUID.randomUUID()), WorkgroupI
interface WorkgroupWithAuthI<Z : CitizenWithUserI> : WorkgroupWithMembersI<Z>, CreatedBy<Z>, DeletedAt { sealed interface WorkgroupWithAuthI<Z : CitizenWithUserI> : WorkgroupWithMembersI<Z>, CreatedBy<Z>, DeletedAt {
val anonymous: Boolean val anonymous: Boolean
fun isMember(user: UserI): Boolean = members.isMember(user) fun isMember(user: UserI): Boolean = members.isMember(user)
@@ -70,11 +70,11 @@ interface WorkgroupWithAuthI<Z : CitizenWithUserI> : WorkgroupWithMembersI<Z>, C
fun hasRole(expectedRole: Role, user: UserI): Boolean = members.hasRole(expectedRole, user) fun hasRole(expectedRole: Role, user: UserI): Boolean = members.hasRole(expectedRole, user)
fun hasRole(expectedRole: Role, citizen: CitizenI): Boolean = members.hasRole(expectedRole, citizen) fun hasRole(expectedRole: Role, citizen: CitizenI): Boolean = members.hasRole(expectedRole, citizen)
fun getRoles(user: UserI): List<Role> = members.getRoles(user) fun getRoles(user: UserI): Collection<Role> = members.getRoles(user)
fun getRoles(citizen: CitizenI): List<Role> = members.getRoles(citizen) fun getRoles(citizen: CitizenI): Collection<Role> = members.getRoles(citizen)
} }
interface WorkgroupWithMembersI<Z : CitizenI> : WorkgroupI { sealed interface WorkgroupWithMembersI<Z : CitizenI> : WorkgroupI {
val members: List<Member<Z>> val members: List<Member<Z>>
class Member<C : CitizenI>( class Member<C : CitizenI>(
@@ -90,24 +90,24 @@ interface WorkgroupWithMembersI<Z : CitizenI> : WorkgroupI {
} }
} }
fun List<CitizenI>.hasCitizen(citizen: CitizenI): Boolean = this.map { it.id }.contains(citizen.id) fun Collection<CitizenI>.hasCitizen(citizen: CitizenI): Boolean = this.map { it.id }.contains(citizen.id)
fun <Z : CitizenWithUserI> List<Member<Z>>.isMember(user: UserI): Boolean = fun <Z : CitizenWithUserI> Collection<Member<Z>>.isMember(user: UserI): Boolean =
map { it.citizen.user.id }.contains(user.id) map { it.citizen.user.id }.contains(user.id)
fun <Z : CitizenI> List<Member<Z>>.isMember(citizen: CitizenI): Boolean = fun <Z : CitizenI> Collection<Member<Z>>.isMember(citizen: CitizenI): Boolean =
map { it.citizen.id }.contains(citizen.id) map { it.citizen.id }.contains(citizen.id)
fun <Z : CitizenI> List<Member<Z>>.hasRole(expectedRole: Role, citizen: CitizenI): Boolean = fun <Z : CitizenI> Collection<Member<Z>>.hasRole(expectedRole: Role, citizen: CitizenI): Boolean =
any { member -> member.citizen.id == citizen.id && member.roles.any { it == expectedRole } } any { member -> member.citizen.id == citizen.id && member.roles.any { it == expectedRole } }
fun <Z : CitizenWithUserI> List<Member<Z>>.hasRole(expectedRole: Role, user: UserI): Boolean = fun <Z : CitizenWithUserI> Collection<Member<Z>>.hasRole(expectedRole: Role, user: UserI): Boolean =
any { member -> member.citizen.user.id == user.id && member.roles.any { it == expectedRole } } any { member -> member.citizen.user.id == user.id && member.roles.any { it == expectedRole } }
fun <Z : CitizenWithUserI> List<Member<Z>>.getRoles(user: UserI): List<Role> = fun <Z : CitizenWithUserI> Collection<Member<Z>>.getRoles(user: UserI): Collection<Role> =
firstOrNull { it.citizen.user.id == user.id }?.roles ?: emptyList() firstOrNull { it.citizen.user.id == user.id }?.roles ?: emptyList()
fun <Z : CitizenWithUserI> List<Member<Z>>.getRoles(citizen: CitizenI): List<Role> = fun <Z : CitizenWithUserI> Collection<Member<Z>>.getRoles(citizen: CitizenI): Collection<Role> =
firstOrNull { it.citizen.id == citizen.id }?.roles ?: emptyList() firstOrNull { it.citizen.id == citizen.id }?.roles ?: emptyList()
interface WorkgroupI : EntityI interface WorkgroupI : EntityI

View File

@@ -66,7 +66,7 @@ object CreateWorkgroup {
anonymous ?: true, anonymous ?: true,
) )
}.let { workgroup -> }.let { workgroup ->
ac.assert { canCreate(workgroup, citizenOrNull) } ac.canCreate(workgroup, citizenOrNull).assert()
repo.upsert(workgroup) repo.upsert(workgroup)
}.let { w -> }.let { w ->
call.respond( call.respond(

View File

@@ -23,7 +23,7 @@ object DeleteWorkgroup {
delete<DeleteWorkgroupRequest> { delete<DeleteWorkgroupRequest> {
mustBeAuth() mustBeAuth()
repo.findById(it.workgroupId)?.let { workgroup -> repo.findById(it.workgroupId)?.let { workgroup ->
ac.assert { canDelete(workgroup, citizenOrNull) } ac.canDelete(workgroup, citizenOrNull).assert()
repo.delete(workgroup) repo.delete(workgroup)
call.respond(HttpStatusCode.NoContent) call.respond(HttpStatusCode.NoContent)
} ?: call.respond(HttpStatusCode.NotFound) } ?: call.respond(HttpStatusCode.NotFound)

View File

@@ -65,7 +65,7 @@ object EditWorkgroup {
deletedAt = old.deletedAt, deletedAt = old.deletedAt,
members = old.members, members = old.members,
).let { workgroup -> ).let { workgroup ->
ac.assert { canUpdate(workgroup, citizenOrNull) } ac.canUpdate(workgroup, citizenOrNull).assert()
repo.upsert(workgroup) repo.upsert(workgroup)
}.let { }.let {
call.respond(HttpStatusCode.OK, it.toOutput()) call.respond(HttpStatusCode.OK, it.toOutput())

View File

@@ -24,7 +24,7 @@ object GetWorkgroup {
fun Route.getWorkgroup(repo: WorkgroupRepository, ac: WorkgroupAccessControl) { fun Route.getWorkgroup(repo: WorkgroupRepository, ac: WorkgroupAccessControl) {
get<WorkgroupRequest> { get<WorkgroupRequest> {
repo.findById(it.workgroup.id)?.let { workgroup -> repo.findById(it.workgroup.id)?.let { workgroup ->
ac.assert { canView(workgroup, citizenOrNull) } ac.canView(workgroup, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
workgroup.toOutput() workgroup.toOutput()

View File

@@ -69,7 +69,7 @@ object GetWorkgroups {
it.search, it.search,
WorkgroupRepository.Filter(createdById = it.createdBy, members = it.members) WorkgroupRepository.Filter(createdById = it.createdBy, members = it.members)
) )
ac.assert { canView(workgroups.result, citizenOrNull) } ac.canView(workgroups.result, citizenOrNull).assert()
call.respond( call.respond(
HttpStatusCode.OK, HttpStatusCode.OK,
workgroups.toOutput { it.toOutputListing() } workgroups.toOutput { it.toOutputListing() }

View File

@@ -47,7 +47,7 @@ object AddMemberToWorkgroup {
mustBeAuth() mustBeAuth()
repo.findById(it.workgroupId)?.let { workgroup -> repo.findById(it.workgroupId)?.let { workgroup ->
call.getMembersFromRequest().let { members -> call.getMembersFromRequest().let { members ->
ac.assert { canAddMembers(workgroup, citizenOrNull) } ac.canAddMembers(workgroup, citizenOrNull).assert()
repo.addMembers(workgroup, members) repo.addMembers(workgroup, members)
}.let { members -> }.let { members ->
call.respond( call.respond(

View File

@@ -39,7 +39,7 @@ object DeleteMembersOfWorkgroup {
repo.findById(it.workgroupId)?.let { workgroup -> repo.findById(it.workgroupId)?.let { workgroup ->
call.getMembersFromRequest() call.getMembersFromRequest()
.let { members -> .let { members ->
ac.assert { canRemoveMembers(workgroup, citizenOrNull) } ac.canRemoveMembers(workgroup, citizenOrNull).assert()
repo.removeMembers(workgroup, members) repo.removeMembers(workgroup, members)
}.let { members -> }.let { members ->
call.respond( call.respond(

View File

@@ -45,7 +45,7 @@ object UpdateMemberOfWorkgroup {
mustBeAuth() mustBeAuth()
repo.findById(it.workgroupId)?.let { workgroup -> repo.findById(it.workgroupId)?.let { workgroup ->
call.getMembersFromRequest().let { members -> call.getMembersFromRequest().let { members ->
ac.assert { canUpdateMembers(workgroup, citizenOrNull) } ac.canUpdateMembers(workgroup, citizenOrNull).assert()
repo.updateMembers(workgroup, members) repo.updateMembers(workgroup, members)
}.let { members -> }.let { members ->
call.respond( call.respond(

View File

@@ -20,8 +20,8 @@ import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
import org.koin.ktor.ext.get import org.koin.ktor.ext.get
import java.util.UUID import java.util.UUID
import kotlin.time.Duration.Companion.seconds
import kotlin.time.ExperimentalTime import kotlin.time.ExperimentalTime
import kotlin.time.seconds
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@ExperimentalCoroutinesApi @ExperimentalCoroutinesApi
@@ -78,7 +78,7 @@ class ViewTest {
) )
/* Retry because ES is not sync ! */ /* Retry because ES is not sync ! */
retry(10, 0.3.seconds) { retry(10, seconds(0.3)) {
/* Get view */ /* Get view */
val afterView = viewRepository.getViewsCount(article) val afterView = viewRepository.getViewsCount(article)

View File

@@ -35,7 +35,7 @@ class `Check auth on all routes` : BaseTest() {
/* Send request to check security */ /* Send request to check security */
sendRequest( sendRequest(
path.buildUrl(pathName, methodName, api.context), /* Replace route to real URL */ path.buildUrl(pathName, methodName, api.context), /* Replace route to real URL */
HttpMethod.parse(methodName.toUpperCase()) /* Convert http method name to enum */ HttpMethod.parse(methodName.lowercase()) /* Convert http method name to enum */
) )
} }
}.let { requests -> }.let { requests ->

View File

@@ -13,7 +13,7 @@ fun TestApplicationRequest.`authenticated as`(
firstName: String, firstName: String,
lastName: String, lastName: String,
): Citizen { ): Citizen {
val username = "$firstName-$lastName".toLowerCase() val username = "$firstName-$lastName".lowercase()
val repo: CitizenRepository by lazy<CitizenRepository> { GlobalContext.get().get() } val repo: CitizenRepository by lazy<CitizenRepository> { GlobalContext.get().get() }
val citizen = repo.findByUsername(username) ?: error("Citizen not exist with username $username") val citizen = repo.findByUsername(username) ?: error("Citizen not exist with username $username")
val algorithm = GlobalContext.get().get<JwtConfig>().algorithm val algorithm = GlobalContext.get().get<JwtConfig>().algorithm

View File

@@ -14,7 +14,7 @@ import java.util.UUID
fun TestApplicationEngine.`Given I have citizen`( fun TestApplicationEngine.`Given I have citizen`(
firstName: String, firstName: String,
lastName: String, lastName: String,
email: String = ("$firstName-$lastName".toLowerCase()) + "@dc-project.fr", email: String = ("$firstName-$lastName".lowercase()) + "@dc-project.fr",
id: String = UUID.randomUUID().toString(), id: String = UUID.randomUUID().toString(),
callback: Citizen.() -> Unit = {} callback: Citizen.() -> Unit = {}
): Citizen? { ): Citizen? {
@@ -22,7 +22,7 @@ fun TestApplicationEngine.`Given I have citizen`(
val user = UserForCreate( val user = UserForCreate(
id = id.toUUID(), id = id.toUUID(),
username = "$firstName-$lastName".toLowerCase(), username = "$firstName-$lastName".lowercase(),
password = "Azerty123!", password = "Azerty123!",
) )
val citizen = CitizenForCreate( val citizen = CitizenForCreate(

View File

@@ -62,7 +62,7 @@ private fun createWorkgroup(
val creatorName = createdBy ?: CitizenI.Name("Paul", "Langevin") val creatorName = createdBy ?: CitizenI.Name("Paul", "Langevin")
val creator = citizenRepository.findByName(creatorName) ?: run { val creator = citizenRepository.findByName(creatorName) ?: run {
val username = ("username" + UUID.randomUUID().toString()) val username = ("username" + UUID.randomUUID().toString())
.toLowerCase().replace(' ', '-') .lowercase().replace(' ', '-')
val user = UserForCreate( val user = UserForCreate(
username = username, username = username,
password = "Azerty123!", password = "Azerty123!",

View File

@@ -46,7 +46,7 @@ fun TestApplicationResponse.operation(route: String? = null, callback: Operation
.firstOrNull { uri.matches(it.replace("""\{[^{}]+}""".toRegex(), "[^/]+").toRegex()) } .firstOrNull { uri.matches(it.replace("""\{[^{}]+}""".toRegex(), "[^/]+").toRegex()) }
api.getPath(path) api.getPath(path)
?.getOperation(httpMethod.value.toLowerCase()) ?.getOperation(httpMethod.value.lowercase())
?.apply { ?.apply {
this.callback(api, uri) this.callback(api, uri)
} }
@@ -59,7 +59,7 @@ fun TestApplicationResponse.`And the schema response body must be valid`(content
/* Validate Response */ /* Validate Response */
this.apply { this.apply {
val status = call.response.status() val status = call.response.status()
val httpMethod = call.request.httpMethod.value.toUpperCase() val httpMethod = call.request.httpMethod.value.lowercase()
val responseContent: JsonNode = if (content != null) val responseContent: JsonNode = if (content != null)
ObjectMapper().readTree(content) ObjectMapper().readTree(content)
else TextNode("") else TextNode("")
@@ -79,7 +79,7 @@ fun TestApplicationResponse.`And the schema parameters must be valid`() {
operation { api, uri -> operation { api, uri ->
/* Validate Request URL */ /* Validate Request URL */
this.apply { this.apply {
val methodName = call.request.httpMethod.value.toUpperCase() val methodName = call.request.httpMethod.value.lowercase()
Url(call.request.uri).parameters.forEach { parameter: String, values: List<String> -> Url(call.request.uri).parameters.forEach { parameter: String, values: List<String> ->
val schema = getParametersIn(api.context, "query") val schema = getParametersIn(api.context, "query")
?.firstOrNull { it.name == parameter }?.schema ?.firstOrNull { it.name == parameter }?.schema
@@ -103,7 +103,7 @@ fun TestApplicationResponse.`And the schema parameters must be valid`() {
* Validate request body * Validate request body
*/ */
fun TestApplicationResponse.`And the schema request body must be valid`(body: String) { fun TestApplicationResponse.`And the schema request body must be valid`(body: String) {
operation { api, uri -> operation { api, _ ->
requestBody requestBody
.getContentMediaType(call.request.contentType().toString()) .getContentMediaType(call.request.contentType().toString())
.schema .schema

View File

@@ -15,15 +15,15 @@ import io.ktor.server.testing.TestApplicationRequest
import io.ktor.server.testing.setBody import io.ktor.server.testing.setBody
enum class Validate(override val bit: Long) : BitMaskI { enum class Validate(override val bit: Long) : BitMaskI {
NONE(0), NONE(0L),
REQUEST_BODY(1), REQUEST_BODY(1L),
REQUEST_PARAM(2), REQUEST_PARAM(2L),
REQUEST_HEADER(4), REQUEST_HEADER(4L),
REQUEST(1 + 2 + 4), REQUEST(1L + 2L + 4L),
RESPONSE_BODY(8), RESPONSE_BODY(8L),
RESPONSE_HEADER(16), RESPONSE_HEADER(16L),
RESPONSE(8 + 16), RESPONSE(8L + 16L),
ALL((1 + 2 + 4) + (8 + 16)); ALL((1L + 2L + 4L) + (8L + 16L));
operator fun unaryMinus(): BitMaskI = ALL - BitMask(this.bit) operator fun unaryMinus(): BitMaskI = ALL - BitMask(this.bit)
} }

View File

@@ -41,7 +41,7 @@ internal class `Article Access Control` {
private val einstein = CitizenCart( private val einstein = CitizenCart(
user = User( user = User(
username = "albert-einstein", username = "albert-einstein",
roles = listOf(UserI.Roles.ROLE_USER) roles = setOf(UserI.Roles.ROLE_USER)
), ),
name = CitizenI.Name("Albert", "Einstein") name = CitizenI.Name("Albert", "Einstein")
) )

View File

@@ -23,14 +23,14 @@ internal class `Citizen Access Control` {
private val tesla = CitizenCart( private val tesla = CitizenCart(
user = User( user = User(
username = "nicolas-tesla", username = "nicolas-tesla",
roles = listOf(UserI.Roles.ROLE_USER) roles = setOf(UserI.Roles.ROLE_USER)
), ),
name = CitizenI.Name("Nicolas", "Tesla") name = CitizenI.Name("Nicolas", "Tesla")
) )
private val einstein = CitizenCart( private val einstein = CitizenCart(
user = User( user = User(
username = "albert-einstein", username = "albert-einstein",
roles = listOf(UserI.Roles.ROLE_USER) roles = setOf(UserI.Roles.ROLE_USER)
), ),
name = CitizenI.Name("Albert", "Einstein") name = CitizenI.Name("Albert", "Einstein")
) )
@@ -38,7 +38,7 @@ internal class `Citizen Access Control` {
private val curie = CitizenCart( private val curie = CitizenCart(
user = User( user = User(
username = "marie-curie", username = "marie-curie",
roles = listOf(UserI.Roles.ROLE_USER) roles = setOf(UserI.Roles.ROLE_USER)
), ),
name = CitizenI.Name("Marie", "Curie"), name = CitizenI.Name("Marie", "Curie"),
deletedAt = DateTime.now() deletedAt = DateTime.now()

View File

@@ -30,7 +30,7 @@ internal class `Comment Access Control` {
private val tesla = Citizen( private val tesla = Citizen(
user = User( user = User(
username = "nicolas-tesla", username = "nicolas-tesla",
roles = listOf(UserI.Roles.ROLE_USER) roles = setOf(UserI.Roles.ROLE_USER)
), ),
birthday = DateTime.now(), birthday = DateTime.now(),
email = "tesla@best.com", email = "tesla@best.com",
@@ -40,7 +40,7 @@ internal class `Comment Access Control` {
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"), id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
user = User( user = User(
username = "albert-einstein", username = "albert-einstein",
roles = listOf(UserI.Roles.ROLE_USER) roles = setOf(UserI.Roles.ROLE_USER)
), ),
birthday = DateTime.now(), birthday = DateTime.now(),
email = "einstein@best.com", email = "einstein@best.com",

View File

@@ -36,7 +36,7 @@ internal class `Follow Access Control` {
private val tesla2 = Citizen( private val tesla2 = Citizen(
user = User( user = User(
username = "nicolas-tesla", username = "nicolas-tesla",
roles = listOf(UserI.Roles.ROLE_USER) roles = setOf(UserI.Roles.ROLE_USER)
), ),
birthday = DateTime.now(), birthday = DateTime.now(),
email = "tesla@best.com", email = "tesla@best.com",
@@ -67,7 +67,7 @@ internal class `Follow Access Control` {
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"), id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
user = User( user = User(
username = "albert-einstein", username = "albert-einstein",
roles = listOf(UserI.Roles.ROLE_USER) roles = setOf(UserI.Roles.ROLE_USER)
), ),
birthday = DateTime.now(), birthday = DateTime.now(),
email = "einstein@best.com", email = "einstein@best.com",

View File

@@ -30,7 +30,7 @@ internal class `Vote Access Control` {
id = UUID.fromString("a1e35c99-9d33-4fb4-9201-58d7071243bb"), id = UUID.fromString("a1e35c99-9d33-4fb4-9201-58d7071243bb"),
user = User( user = User(
username = "nicolas-tesla", username = "nicolas-tesla",
roles = listOf(UserI.Roles.ROLE_USER) roles = setOf(UserI.Roles.ROLE_USER)
), ),
birthday = DateTime.now(), birthday = DateTime.now(),
email = "tesla@best.com", email = "tesla@best.com",
@@ -51,7 +51,7 @@ internal class `Vote Access Control` {
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"), id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
user = User( user = User(
username = "albert-einstein", username = "albert-einstein",
roles = listOf(UserI.Roles.ROLE_USER) roles = setOf(UserI.Roles.ROLE_USER)
), ),
birthday = DateTime.now(), birthday = DateTime.now(),
email = "einstein@best.com", email = "einstein@best.com",

View File

@@ -15,15 +15,15 @@ fi
case $opt in case $opt in
"RESET DB") "RESET DB")
awk 'FNR==1{print "--------------------"}1' \ awk 'FNR==1{print "--------------------"}1' \
../../main/resources/sql/migrations/*.down.sql \ ../../../main/resources/sql/migrations/*.down.sql \
../../main/resources/sql/migrations/*.up.sql > ./allSQL.sql ../../../main/resources/sql/migrations/*.up.sql > ./allSQL.sql
docker exec -i dc-project_postgresql_test psql test test -q -b -v "ON_ERROR_STOP=1" < ./allSQL.sql docker exec -i dc-project_postgresql_test psql test test -q -b -v "ON_ERROR_STOP=1" < ./allSQL.sql
rm ./allSQL.sql rm ./allSQL.sql
;; ;;
"All") "All")
echo "Start ALL tests" echo "Start ALL tests"
awk 'FNR==1{print "--------------------"}1' \ awk 'FNR==1{print "--------------------"}1' \
../../main/resources/sql/functions/*/*.sql \ ../../../main/resources/sql/functions/*/*.sql \
./fixtures/*.sql \ ./fixtures/*.sql \
./*.sql > ./allSQL.sql ./*.sql > ./allSQL.sql
docker exec -i dc-project_postgresql_test psql test test -q -b -v "ON_ERROR_STOP=1" < ./allSQL.sql docker exec -i dc-project_postgresql_test psql test test -q -b -v "ON_ERROR_STOP=1" < ./allSQL.sql
@@ -34,7 +34,7 @@ case $opt in
*) *)
echo "Start tests $opt" echo "Start tests $opt"
awk 'FNR==1{print "--------------------"}1' \ awk 'FNR==1{print "--------------------"}1' \
../../main/resources/sql/functions/*/*.sql \ ../../../main/resources/sql/functions/*/*.sql \
./fixtures/*.sql \ ./fixtures/*.sql \
./"$opt".sql > ./allSQL.sql ./"$opt".sql > ./allSQL.sql
docker exec -i dc-project_postgresql_test psql test test -q -b -v "ON_ERROR_STOP=1" < ./allSQL.sql docker exec -i dc-project_postgresql_test psql test test -q -b -v "ON_ERROR_STOP=1" < ./allSQL.sql