Big refactoring #77
@@ -20,6 +20,7 @@ import fr.dcproject.component.follow.routes.article.installFollowArticleRoutes
|
||||
import fr.dcproject.component.follow.routes.constitution.installFollowConstitutionRoutes
|
||||
import fr.dcproject.component.opinion.routes.installOpinionRoutes
|
||||
import fr.dcproject.component.views.ConfigViews
|
||||
import fr.dcproject.component.vote.routes.installVoteRoutes
|
||||
import fr.dcproject.component.workgroup.routes.installWorkgroupRoutes
|
||||
import fr.dcproject.event.EventNotification
|
||||
import fr.dcproject.event.EventSubscriber
|
||||
@@ -27,8 +28,6 @@ import fr.dcproject.routes.commentConstitution
|
||||
import fr.dcproject.routes.constitution
|
||||
import fr.dcproject.routes.definition
|
||||
import fr.dcproject.routes.notificationArticle
|
||||
import fr.dcproject.routes.voteArticle
|
||||
import fr.dcproject.routes.voteConstitution
|
||||
import fr.dcproject.voter.VoterDeniedException
|
||||
import fr.postgresjson.migration.Migrations
|
||||
import io.ktor.application.Application
|
||||
@@ -140,13 +139,12 @@ fun Application.module(env: Env = PROD) {
|
||||
installFollowConstitutionRoutes()
|
||||
installWorkgroupRoutes()
|
||||
installOpinionRoutes()
|
||||
installVoteRoutes()
|
||||
|
||||
authenticate(optional = true) {
|
||||
/* TODO */
|
||||
constitution(get(), get())
|
||||
commentConstitution(get(), get())
|
||||
voteArticle(get(), get(), get(), get())
|
||||
voteConstitution(get(), get())
|
||||
definition()
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ import fr.dcproject.component.citizen.CitizenBasic
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.citizen.CitizenRepository
|
||||
import fr.dcproject.component.comment.generic.CommentRef
|
||||
import fr.dcproject.component.opinion.OpinionChoiceRepository
|
||||
import fr.dcproject.component.opinion.entity.OpinionChoice
|
||||
import fr.dcproject.component.workgroup.Workgroup
|
||||
import fr.dcproject.component.workgroup.WorkgroupRef
|
||||
import fr.dcproject.component.workgroup.WorkgroupRepository
|
||||
import fr.dcproject.entity.Constitution
|
||||
import fr.dcproject.entity.ConstitutionRef
|
||||
import fr.dcproject.repository.OpinionChoiceRepository
|
||||
import io.ktor.features.DataConversion
|
||||
import io.ktor.features.NotFoundException
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
|
||||
@@ -18,8 +18,14 @@ import fr.dcproject.component.citizen.CitizenVoter
|
||||
import fr.dcproject.component.comment.article.CommentArticleRepository
|
||||
import fr.dcproject.component.comment.generic.CommentVoter
|
||||
import fr.dcproject.component.follow.FollowVoter
|
||||
import fr.dcproject.component.opinion.OpinionChoiceRepository
|
||||
import fr.dcproject.component.opinion.OpinionChoiceVoter
|
||||
import fr.dcproject.component.opinion.OpinionVoter
|
||||
import fr.dcproject.component.vote.VoteArticleRepository
|
||||
import fr.dcproject.component.vote.VoteCommentRepository
|
||||
import fr.dcproject.component.vote.VoteConstitutionRepository
|
||||
import fr.dcproject.component.vote.VoteRepository
|
||||
import fr.dcproject.component.vote.VoteVoter
|
||||
import fr.dcproject.component.workgroup.WorkgroupRepository
|
||||
import fr.dcproject.component.workgroup.WorkgroupVoter
|
||||
import fr.dcproject.event.publisher.Publisher
|
||||
@@ -27,7 +33,6 @@ import fr.dcproject.messages.Mailer
|
||||
import fr.dcproject.messages.NotificationEmailSender
|
||||
import fr.dcproject.repository.CommentConstitutionRepository
|
||||
import fr.dcproject.security.voter.ConstitutionVoter
|
||||
import fr.dcproject.security.voter.VoteVoter
|
||||
import fr.postgresjson.connexion.Connection
|
||||
import fr.postgresjson.connexion.Requester
|
||||
import fr.postgresjson.migration.Migrations
|
||||
@@ -43,12 +48,8 @@ import org.koin.dsl.module
|
||||
import fr.dcproject.component.comment.generic.CommentRepository as CommentGenericRepository
|
||||
import fr.dcproject.component.follow.FollowArticleRepository as FollowArticleRepository
|
||||
import fr.dcproject.component.follow.FollowConstitutionRepository as FollowConstitutionRepository
|
||||
import fr.dcproject.component.opinion.OpinionRepositoryArticle as OpinionArticleRepository
|
||||
import fr.dcproject.repository.Constitution as ConstitutionRepository
|
||||
import fr.dcproject.repository.OpinionChoiceRepository as OpinionChoiceRepository
|
||||
import fr.dcproject.repository.OpinionRepositoryArticle as OpinionArticleRepository
|
||||
import fr.dcproject.repository.VoteArticle as VoteArticleRepository
|
||||
import fr.dcproject.repository.VoteComment as VoteCommentRepository
|
||||
import fr.dcproject.repository.VoteConstitution as VoteConstitutionRepository
|
||||
|
||||
@KtorExperimentalAPI
|
||||
val KoinModule = module {
|
||||
@@ -116,6 +117,7 @@ val KoinModule = module {
|
||||
single { CommentGenericRepository(get()) }
|
||||
single { CommentArticleRepository(get()) }
|
||||
single { CommentConstitutionRepository(get()) }
|
||||
single { VoteRepository(get()) }
|
||||
single { VoteArticleRepository(get()) }
|
||||
single { VoteConstitutionRepository(get()) }
|
||||
single { VoteCommentRepository(get()) }
|
||||
|
||||
@@ -9,6 +9,8 @@ import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.opinion.entity.Opinionable
|
||||
import fr.dcproject.component.opinion.entity.OpinionableImp
|
||||
import fr.dcproject.component.opinion.entity.Opinions
|
||||
import fr.dcproject.component.vote.entity.Votable
|
||||
import fr.dcproject.component.vote.entity.VotableImp
|
||||
import fr.dcproject.component.workgroup.WorkgroupCart
|
||||
import fr.dcproject.component.workgroup.WorkgroupCartI
|
||||
import fr.dcproject.component.workgroup.WorkgroupRef
|
||||
@@ -19,8 +21,6 @@ import fr.dcproject.entity.TargetI
|
||||
import fr.dcproject.entity.TargetRef
|
||||
import fr.dcproject.entity.VersionableRef
|
||||
import fr.dcproject.entity.VersionableRefImp
|
||||
import fr.dcproject.entity.Votable
|
||||
import fr.dcproject.entity.VotableImp
|
||||
import fr.postgresjson.entity.EntityCreatedAt
|
||||
import fr.postgresjson.entity.EntityCreatedAtImp
|
||||
import fr.postgresjson.entity.EntityDeletedAt
|
||||
|
||||
@@ -7,10 +7,10 @@ import fr.dcproject.component.article.ArticleVoter
|
||||
import fr.dcproject.component.article.routes.GetOneArticle.ArticleRequest.Output
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.opinion.dto.Opinionable
|
||||
import fr.dcproject.component.vote.dto.Votable
|
||||
import fr.dcproject.dto.CreatedAt
|
||||
import fr.dcproject.dto.Versionable
|
||||
import fr.dcproject.dto.Viewable
|
||||
import fr.dcproject.dto.Votable
|
||||
import fr.dcproject.voter.assert
|
||||
import io.ktor.application.call
|
||||
import io.ktor.features.NotFoundException
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package fr.dcproject.component.comment.generic
|
||||
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.vote.entity.Votable
|
||||
import fr.dcproject.component.vote.entity.VotableImp
|
||||
import fr.dcproject.entity.EntityI
|
||||
import fr.dcproject.entity.ExtraI
|
||||
import fr.dcproject.entity.HasTarget
|
||||
import fr.dcproject.entity.TargetI
|
||||
import fr.dcproject.entity.TargetRef
|
||||
import fr.dcproject.entity.Votable
|
||||
import fr.dcproject.entity.VotableImp
|
||||
import fr.postgresjson.entity.EntityCreatedAt
|
||||
import fr.postgresjson.entity.EntityCreatedAtImp
|
||||
import fr.postgresjson.entity.EntityCreatedBy
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package fr.dcproject.repository
|
||||
package fr.dcproject.component.opinion
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference
|
||||
import fr.dcproject.component.article.ArticleRef
|
||||
|
||||
@@ -15,7 +15,7 @@ import io.ktor.routing.Route
|
||||
import org.koin.core.KoinComponent
|
||||
import java.util.UUID
|
||||
import fr.dcproject.component.citizen.Citizen as CitizenEntity
|
||||
import fr.dcproject.repository.OpinionRepositoryArticle as OpinionArticleRepository
|
||||
import fr.dcproject.component.opinion.OpinionRepositoryArticle as OpinionArticleRepository
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object GetCitizenOpinions {
|
||||
|
||||
@@ -13,7 +13,7 @@ import io.ktor.locations.Location
|
||||
import io.ktor.locations.get
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import fr.dcproject.repository.OpinionRepositoryArticle as OpinionArticleRepository
|
||||
import fr.dcproject.component.opinion.OpinionRepositoryArticle as OpinionArticleRepository
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object GetMyOpinionsArticle {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package fr.dcproject.component.opinion.routes
|
||||
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.opinion.OpinionChoiceRepository
|
||||
import fr.dcproject.component.opinion.OpinionChoiceVoter
|
||||
import fr.dcproject.voter.assert
|
||||
import io.ktor.application.call
|
||||
@@ -9,7 +10,6 @@ import io.ktor.locations.Location
|
||||
import io.ktor.locations.get
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import fr.dcproject.repository.OpinionChoiceRepository as OpinionChoiceRepository
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object GetOpinionChoices {
|
||||
|
||||
@@ -17,7 +17,7 @@ import io.ktor.request.receive
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import java.util.UUID
|
||||
import fr.dcproject.repository.OpinionRepositoryArticle as OpinionArticleRepository
|
||||
import fr.dcproject.component.opinion.OpinionRepositoryArticle as OpinionArticleRepository
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object OpinionArticle {
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
package fr.dcproject.repository
|
||||
package fr.dcproject.component.vote
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.comment.generic.CommentForView
|
||||
import fr.dcproject.component.vote.entity.VoteAggregation
|
||||
import fr.dcproject.component.vote.entity.VoteForUpdateI
|
||||
import fr.dcproject.entity.Constitution
|
||||
import fr.dcproject.entity.TargetI
|
||||
import fr.dcproject.entity.TargetRef
|
||||
import fr.dcproject.entity.VoteAggregation
|
||||
import fr.dcproject.entity.VoteForUpdateI
|
||||
import fr.postgresjson.connexion.Paginated
|
||||
import fr.postgresjson.connexion.Requester
|
||||
import fr.postgresjson.repository.RepositoryI
|
||||
import java.util.UUID
|
||||
import fr.dcproject.component.citizen.Citizen as CitizenEntity
|
||||
import fr.dcproject.entity.Vote as VoteEntity
|
||||
import fr.dcproject.component.vote.entity.Vote as VoteEntity
|
||||
|
||||
open class Vote<T : TargetI>(override var requester: Requester) : RepositoryI {
|
||||
abstract class VoteRepositoryAbs<T : TargetI>(override var requester: Requester) : RepositoryI {
|
||||
fun vote(vote: VoteForUpdateI<T, *>, anonymous: Boolean? = null): VoteAggregation {
|
||||
val author = vote.createdBy
|
||||
return requester
|
||||
@@ -69,7 +69,9 @@ open class Vote<T : TargetI>(override var requester: Requester) : RepositoryI {
|
||||
}
|
||||
}
|
||||
|
||||
class VoteArticle(requester: Requester) : Vote<ArticleForView>(requester) {
|
||||
class VoteRepository(requester: Requester) : VoteRepositoryAbs<TargetRef>(requester)
|
||||
|
||||
class VoteArticleRepository(requester: Requester) : VoteRepositoryAbs<ArticleForView>(requester) {
|
||||
fun findByCitizen(
|
||||
citizen: CitizenEntity,
|
||||
page: Int = 1,
|
||||
@@ -84,7 +86,7 @@ class VoteArticle(requester: Requester) : Vote<ArticleForView>(requester) {
|
||||
)
|
||||
}
|
||||
|
||||
class VoteArticleComment(requester: Requester) : Vote<CommentForView<ArticleForView, CitizenRef>>(requester) {
|
||||
class VoteArticleCommentRepository(requester: Requester) : VoteRepositoryAbs<CommentForView<ArticleForView, CitizenRef>>(requester) {
|
||||
fun findByCitizen(
|
||||
citizen: CitizenEntity,
|
||||
page: Int = 1,
|
||||
@@ -99,7 +101,7 @@ class VoteArticleComment(requester: Requester) : Vote<CommentForView<ArticleForV
|
||||
)
|
||||
}
|
||||
|
||||
class VoteComment(requester: Requester) : Vote<CommentForView<TargetRef, CitizenRef>>(requester) {
|
||||
class VoteCommentRepository(requester: Requester) : VoteRepositoryAbs<CommentForView<TargetRef, CitizenRef>>(requester) {
|
||||
fun findByCitizen(
|
||||
citizen: CitizenEntity,
|
||||
page: Int = 1,
|
||||
@@ -114,7 +116,7 @@ class VoteComment(requester: Requester) : Vote<CommentForView<TargetRef, Citizen
|
||||
)
|
||||
}
|
||||
|
||||
class VoteConstitution(requester: Requester) : Vote<Constitution>(requester) {
|
||||
class VoteConstitutionRepository(requester: Requester) : VoteRepositoryAbs<Constitution>(requester) {
|
||||
fun findByCitizen(
|
||||
citizen: CitizenEntity,
|
||||
page: Int = 1,
|
||||
@@ -1,12 +1,12 @@
|
||||
package fr.dcproject.security.voter
|
||||
package fr.dcproject.component.vote
|
||||
|
||||
import fr.dcproject.component.citizen.CitizenI
|
||||
import fr.dcproject.component.vote.entity.VoteForUpdateI
|
||||
import fr.dcproject.entity.TargetI
|
||||
import fr.dcproject.entity.VoteForUpdateI
|
||||
import fr.dcproject.voter.Voter
|
||||
import fr.dcproject.voter.VoterResponse
|
||||
import fr.postgresjson.entity.EntityDeletedAt
|
||||
import fr.dcproject.entity.Vote as VoteEntity
|
||||
import fr.dcproject.component.vote.entity.Vote as VoteEntity
|
||||
|
||||
class VoteVoter : Voter() {
|
||||
fun <S> canCreate(subject: VoteForUpdateI<S, *>, citizen: CitizenI?): VoterResponse where S : EntityDeletedAt, S : TargetI = when {
|
||||
@@ -1,9 +1,9 @@
|
||||
package fr.dcproject.dto
|
||||
package fr.dcproject.component.vote.dto
|
||||
|
||||
interface Votable {
|
||||
val votes: VoteAggregation
|
||||
|
||||
class Imp(parent: fr.dcproject.entity.Votable) : Votable {
|
||||
class Imp(parent: fr.dcproject.component.vote.entity.Votable) : Votable {
|
||||
override val votes: VoteAggregation = VoteAggregation(parent)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package fr.dcproject.dto
|
||||
package fr.dcproject.component.vote.dto
|
||||
|
||||
import fr.dcproject.entity.Votable
|
||||
import fr.dcproject.component.vote.entity.Votable
|
||||
|
||||
class VoteAggregation(parent: Votable) {
|
||||
val up: Int = parent.votes.up
|
||||
@@ -1,4 +1,4 @@
|
||||
package fr.dcproject.entity
|
||||
package fr.dcproject.component.vote.entity
|
||||
|
||||
interface Votable {
|
||||
val votes: VoteAggregation
|
||||
@@ -1,8 +1,11 @@
|
||||
package fr.dcproject.entity
|
||||
package fr.dcproject.component.vote.entity
|
||||
|
||||
import fr.dcproject.component.citizen.CitizenBasic
|
||||
import fr.dcproject.component.citizen.CitizenBasicI
|
||||
import fr.dcproject.component.citizen.CitizenI
|
||||
import fr.dcproject.entity.ExtraI
|
||||
import fr.dcproject.entity.HasTarget
|
||||
import fr.dcproject.entity.TargetI
|
||||
import fr.postgresjson.entity.EntityCreatedAt
|
||||
import fr.postgresjson.entity.EntityCreatedAtImp
|
||||
import fr.postgresjson.entity.EntityCreatedBy
|
||||
@@ -1,10 +1,10 @@
|
||||
package fr.dcproject.entity
|
||||
package fr.dcproject.component.vote.entity
|
||||
|
||||
import fr.postgresjson.entity.EntityI
|
||||
import fr.postgresjson.entity.EntityUpdatedAt
|
||||
import fr.postgresjson.entity.EntityUpdatedAtImp
|
||||
|
||||
open class VoteAggregation(
|
||||
class VoteAggregation(
|
||||
val up: Int,
|
||||
val neutral: Int,
|
||||
val down: Int,
|
||||
33
src/main/kotlin/component/vote/routes/GetCitizenVotes.kt
Normal file
33
src/main/kotlin/component/vote/routes/GetCitizenVotes.kt
Normal file
@@ -0,0 +1,33 @@
|
||||
package fr.dcproject.component.vote.routes
|
||||
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.component.vote.VoteRepository
|
||||
import fr.dcproject.component.vote.VoteVoter
|
||||
import fr.dcproject.utils.toUUID
|
||||
import fr.dcproject.voter.assert
|
||||
import io.ktor.application.call
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Location
|
||||
import io.ktor.locations.get
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import java.util.UUID
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object GetCitizenVotes {
|
||||
@Location("/citizens/{citizen}/votes")
|
||||
class CitizenVotesRequest(val citizen: Citizen, id: List<String>) {
|
||||
val id: List<UUID> = id.toUUID()
|
||||
}
|
||||
|
||||
fun Route.getCitizenVote(repo: VoteRepository, voter: VoteVoter) {
|
||||
get<CitizenVotesRequest> {
|
||||
val votes = repo.findCitizenVotesByTargets(it.citizen, it.id)
|
||||
if (votes.isNotEmpty()) {
|
||||
voter.assert { canView(votes, citizenOrNull) }
|
||||
}
|
||||
call.respond(votes)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package fr.dcproject.component.vote.routes
|
||||
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.component.vote.VoteArticleRepository
|
||||
import fr.dcproject.component.vote.VoteVoter
|
||||
import fr.dcproject.routes.PaginatedRequest
|
||||
import fr.dcproject.routes.PaginatedRequestI
|
||||
import fr.dcproject.voter.assert
|
||||
import io.ktor.application.call
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Location
|
||||
import io.ktor.locations.get
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object GetCitizenVotesOnArticle {
|
||||
@Location("/citizens/{citizen}/votes/articles")
|
||||
class CitizenVoteArticleRequest(
|
||||
val citizen: Citizen,
|
||||
page: Int = 1,
|
||||
limit: Int = 50,
|
||||
val search: String? = null
|
||||
) : PaginatedRequestI by PaginatedRequest(page, limit)
|
||||
|
||||
fun Route.getCitizenVotesOnArticle(repo: VoteArticleRepository, voter: VoteVoter) {
|
||||
get<CitizenVoteArticleRequest> {
|
||||
val votes = repo.findByCitizen(it.citizen, it.page, it.limit)
|
||||
voter.assert { canView(votes.result, citizenOrNull) }
|
||||
|
||||
call.respond(votes)
|
||||
}
|
||||
}
|
||||
}
|
||||
39
src/main/kotlin/component/vote/routes/PutVoteOnArticle.kt
Normal file
39
src/main/kotlin/component/vote/routes/PutVoteOnArticle.kt
Normal file
@@ -0,0 +1,39 @@
|
||||
package fr.dcproject.component.vote.routes
|
||||
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.component.auth.citizen
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.vote.VoteArticleRepository
|
||||
import fr.dcproject.component.vote.VoteVoter
|
||||
import fr.dcproject.component.vote.entity.VoteForUpdate
|
||||
import fr.dcproject.voter.assert
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Location
|
||||
import io.ktor.locations.put
|
||||
import io.ktor.request.receive
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object PutVoteOnArticle {
|
||||
@Location("/articles/{article}/vote")
|
||||
class ArticleVoteRequest(val article: ArticleForView) {
|
||||
data class Content(var note: Int)
|
||||
}
|
||||
|
||||
fun Route.putVoteOnArticle(repo: VoteArticleRepository, voter: VoteVoter) {
|
||||
put<ArticleVoteRequest> {
|
||||
val content = call.receive<ArticleVoteRequest.Content>()
|
||||
val vote = VoteForUpdate(
|
||||
target = it.article,
|
||||
note = content.note,
|
||||
createdBy = this.citizen
|
||||
)
|
||||
voter.assert { canCreate(vote, citizenOrNull) }
|
||||
val votes = repo.vote(vote)
|
||||
call.respond(HttpStatusCode.Created, votes)
|
||||
}
|
||||
}
|
||||
}
|
||||
41
src/main/kotlin/component/vote/routes/PutVoteOnComment.kt
Normal file
41
src/main/kotlin/component/vote/routes/PutVoteOnComment.kt
Normal file
@@ -0,0 +1,41 @@
|
||||
package fr.dcproject.component.vote.routes
|
||||
|
||||
import fr.dcproject.component.auth.citizen
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.comment.generic.CommentRepository
|
||||
import fr.dcproject.component.vote.VoteCommentRepository
|
||||
import fr.dcproject.component.vote.VoteVoter
|
||||
import fr.dcproject.component.vote.entity.VoteForUpdate
|
||||
import fr.dcproject.voter.assert
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Location
|
||||
import io.ktor.locations.put
|
||||
import io.ktor.request.receive
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import java.util.UUID
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object PutVoteOnComment {
|
||||
@Location("/comments/{comment}/vote")
|
||||
class CommentVoteRequest(val comment: UUID) {
|
||||
data class Content(var note: Int)
|
||||
}
|
||||
|
||||
fun Route.putVoteOnComment(voteCommentRepo: VoteCommentRepository, commentRepo: CommentRepository, voter: VoteVoter) {
|
||||
put<CommentVoteRequest> {
|
||||
val comment = commentRepo.findById(it.comment)!!
|
||||
val content = call.receive<CommentVoteRequest.Content>()
|
||||
val vote = VoteForUpdate(
|
||||
target = comment,
|
||||
note = content.note,
|
||||
createdBy = this.citizen
|
||||
)
|
||||
voter.assert { canCreate(vote, citizenOrNull) }
|
||||
val votes = voteCommentRepo.vote(vote)
|
||||
call.respond(HttpStatusCode.Created, votes)
|
||||
}
|
||||
}
|
||||
}
|
||||
40
src/main/kotlin/component/vote/routes/VoteConstitution.kt
Normal file
40
src/main/kotlin/component/vote/routes/VoteConstitution.kt
Normal file
@@ -0,0 +1,40 @@
|
||||
package fr.dcproject.component.vote.routes
|
||||
|
||||
import fr.dcproject.component.auth.citizen
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.vote.VoteConstitutionRepository
|
||||
import fr.dcproject.component.vote.VoteVoter
|
||||
import fr.dcproject.component.vote.entity.VoteForUpdate
|
||||
import fr.dcproject.component.vote.routes.VoteConstitution.ConstitutionVoteRequest.Input
|
||||
import fr.dcproject.voter.assert
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Location
|
||||
import io.ktor.locations.put
|
||||
import io.ktor.request.receive
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import fr.dcproject.entity.Constitution as ConstitutionEntity
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object VoteConstitution {
|
||||
@Location("/constitutions/{constitution}/vote")
|
||||
class ConstitutionVoteRequest(val constitution: ConstitutionEntity) {
|
||||
data class Input(var note: Int)
|
||||
}
|
||||
|
||||
fun Route.voteConstitution(repo: VoteConstitutionRepository, voter: VoteVoter) {
|
||||
put<ConstitutionVoteRequest> {
|
||||
val content = call.receive<Input>()
|
||||
val vote = VoteForUpdate(
|
||||
target = it.constitution,
|
||||
note = content.note,
|
||||
createdBy = this.citizen
|
||||
)
|
||||
voter.assert { canCreate(vote, citizenOrNull) }
|
||||
repo.vote(vote)
|
||||
call.respond(HttpStatusCode.Created)
|
||||
}
|
||||
}
|
||||
}
|
||||
22
src/main/kotlin/component/vote/routes/install.kt
Normal file
22
src/main/kotlin/component/vote/routes/install.kt
Normal file
@@ -0,0 +1,22 @@
|
||||
package fr.dcproject.component.vote.routes
|
||||
|
||||
import fr.dcproject.component.vote.routes.GetCitizenVotes.getCitizenVote
|
||||
import fr.dcproject.component.vote.routes.GetCitizenVotesOnArticle.getCitizenVotesOnArticle
|
||||
import fr.dcproject.component.vote.routes.PutVoteOnArticle.putVoteOnArticle
|
||||
import fr.dcproject.component.vote.routes.PutVoteOnComment.putVoteOnComment
|
||||
import fr.dcproject.component.vote.routes.VoteConstitution.voteConstitution
|
||||
import io.ktor.auth.authenticate
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.routing.Routing
|
||||
import org.koin.ktor.ext.get
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
fun Routing.installVoteRoutes() {
|
||||
authenticate(optional = true) {
|
||||
getCitizenVote(get(), get())
|
||||
getCitizenVotesOnArticle(get(), get())
|
||||
putVoteOnArticle(get(), get())
|
||||
putVoteOnComment(get(), get(), get())
|
||||
voteConstitution(get(), get())
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
package fr.dcproject.routes
|
||||
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.component.auth.citizen
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.component.comment.generic.CommentRepository
|
||||
import fr.dcproject.entity.VoteForUpdate
|
||||
import fr.dcproject.repository.VoteComment
|
||||
import fr.dcproject.routes.VoteArticlePaths.ArticleVoteRequest
|
||||
import fr.dcproject.routes.VoteArticlePaths.CommentVoteRequest
|
||||
import fr.dcproject.security.voter.VoteVoter
|
||||
import fr.dcproject.utils.toUUID
|
||||
import fr.dcproject.voter.assert
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Location
|
||||
import io.ktor.locations.get
|
||||
import io.ktor.locations.put
|
||||
import io.ktor.request.receive
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import java.util.UUID
|
||||
import fr.dcproject.repository.VoteArticle as VoteArticleRepository
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object VoteArticlePaths {
|
||||
@Location("/articles/{article}/vote")
|
||||
class ArticleVoteRequest(val article: ArticleForView) {
|
||||
data class Content(var note: Int)
|
||||
}
|
||||
|
||||
@Location("/comments/{comment}/vote")
|
||||
class CommentVoteRequest(val comment: UUID) {
|
||||
data class Content(var note: Int)
|
||||
}
|
||||
|
||||
@Location("/citizens/{citizen}/votes/articles")
|
||||
class CitizenVoteArticleRequest(
|
||||
val citizen: Citizen,
|
||||
page: Int = 1,
|
||||
limit: Int = 50,
|
||||
val search: String? = null
|
||||
) : PaginatedRequestI by PaginatedRequest(page, limit)
|
||||
|
||||
@Location("/citizens/{citizen}/votes")
|
||||
class CitizenVotesByIdsRequest(val citizen: Citizen, id: List<String>) {
|
||||
val id: List<UUID> = id.toUUID()
|
||||
}
|
||||
}
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
fun Route.voteArticle(repo: VoteArticleRepository, voteCommentRepo: VoteComment, commentRepo: CommentRepository, voter: VoteVoter) {
|
||||
put<ArticleVoteRequest> {
|
||||
val content = call.receive<ArticleVoteRequest.Content>()
|
||||
val vote = VoteForUpdate(
|
||||
target = it.article,
|
||||
note = content.note,
|
||||
createdBy = this.citizen
|
||||
)
|
||||
voter.assert { canCreate(vote, citizenOrNull) }
|
||||
val votes = repo.vote(vote)
|
||||
call.respond(HttpStatusCode.Created, votes)
|
||||
}
|
||||
|
||||
put<CommentVoteRequest> {
|
||||
val comment = commentRepo.findById(it.comment)!!
|
||||
val content = call.receive<CommentVoteRequest.Content>()
|
||||
val vote = VoteForUpdate(
|
||||
target = comment,
|
||||
note = content.note,
|
||||
createdBy = this.citizen
|
||||
)
|
||||
voter.assert { canCreate(vote, citizenOrNull) }
|
||||
val votes = voteCommentRepo.vote(vote)
|
||||
call.respond(HttpStatusCode.Created, votes)
|
||||
}
|
||||
|
||||
get<VoteArticlePaths.CitizenVoteArticleRequest> {
|
||||
val votes = repo.findByCitizen(it.citizen, it.page, it.limit)
|
||||
voter.assert { canView(votes.result, citizenOrNull) }
|
||||
|
||||
call.respond(votes)
|
||||
}
|
||||
|
||||
get<VoteArticlePaths.CitizenVotesByIdsRequest> {
|
||||
val votes = repo.findCitizenVotesByTargets(it.citizen, it.id)
|
||||
if (votes.isNotEmpty()) {
|
||||
voter.assert { canView(votes, citizenOrNull) }
|
||||
}
|
||||
call.respond(votes)
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package fr.dcproject.routes
|
||||
|
||||
import fr.dcproject.component.auth.citizen
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.entity.VoteForUpdate
|
||||
import fr.dcproject.routes.VoteConstitutionPaths.ConstitutionVoteRequest.Content
|
||||
import fr.dcproject.security.voter.VoteVoter
|
||||
import fr.dcproject.voter.assert
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Location
|
||||
import io.ktor.locations.put
|
||||
import io.ktor.request.receive
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import fr.dcproject.entity.Constitution as ConstitutionEntity
|
||||
import fr.dcproject.repository.VoteConstitution as VoteConstitutionRepository
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object VoteConstitutionPaths {
|
||||
@Location("/constitutions/{constitution}/vote")
|
||||
class ConstitutionVoteRequest(val constitution: ConstitutionEntity) {
|
||||
data class Content(var note: Int)
|
||||
}
|
||||
|
||||
@Location("/citizens/{citizen}/votes/constitutions")
|
||||
class CitizenVoteConstitutionRequest(val citizen: Citizen)
|
||||
}
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
fun Route.voteConstitution(repo: VoteConstitutionRepository, voter: VoteVoter) {
|
||||
put<VoteConstitutionPaths.ConstitutionVoteRequest> {
|
||||
val content = call.receive<Content>()
|
||||
val vote = VoteForUpdate(
|
||||
target = it.constitution,
|
||||
note = content.note,
|
||||
createdBy = this.citizen
|
||||
)
|
||||
voter.assert { canCreate(vote, citizenOrNull) }
|
||||
repo.vote(vote)
|
||||
call.respond(HttpStatusCode.Created)
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package steps
|
||||
import fr.dcproject.component.article.ArticleRef
|
||||
import fr.dcproject.component.article.ArticleRepository
|
||||
import fr.dcproject.component.citizen.CitizenRepository
|
||||
import fr.dcproject.component.opinion.OpinionChoiceRepository
|
||||
import fr.dcproject.component.opinion.entity.OpinionChoice
|
||||
import fr.dcproject.component.opinion.entity.OpinionForUpdate
|
||||
import fr.dcproject.utils.toUUID
|
||||
@@ -11,8 +12,7 @@ import io.cucumber.java8.En
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.get
|
||||
import java.util.UUID
|
||||
import fr.dcproject.repository.OpinionChoiceRepository as OpinionChoiceRepository
|
||||
import fr.dcproject.repository.OpinionRepositoryArticle as OpinionRepository
|
||||
import fr.dcproject.component.opinion.OpinionRepositoryArticle as OpinionRepository
|
||||
|
||||
class OpinionSteps : En, KoinTest {
|
||||
init {
|
||||
|
||||
@@ -2,13 +2,13 @@ package steps
|
||||
|
||||
import fr.dcproject.component.article.ArticleRepository
|
||||
import fr.dcproject.component.citizen.CitizenRepository
|
||||
import fr.dcproject.entity.VoteForUpdate
|
||||
import fr.dcproject.component.vote.entity.VoteForUpdate
|
||||
import fr.dcproject.utils.toUUID
|
||||
import io.cucumber.java8.En
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.get
|
||||
import java.util.UUID
|
||||
import fr.dcproject.repository.VoteArticle as VoteRepository
|
||||
import fr.dcproject.component.vote.VoteArticleRepository as VoteRepository
|
||||
|
||||
class VoteSteps : En, KoinTest {
|
||||
init {
|
||||
|
||||
@@ -7,8 +7,8 @@ import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.component.citizen.CitizenBasic
|
||||
import fr.dcproject.component.citizen.CitizenCart
|
||||
import fr.dcproject.component.citizen.CitizenI
|
||||
import fr.dcproject.entity.VoteForUpdate
|
||||
import fr.dcproject.security.voter.VoteVoter
|
||||
import fr.dcproject.component.vote.VoteVoter
|
||||
import fr.dcproject.component.vote.entity.VoteForUpdate
|
||||
import fr.dcproject.voter.Vote.DENIED
|
||||
import fr.dcproject.voter.Vote.GRANTED
|
||||
import org.amshove.kluent.`should be`
|
||||
@@ -19,7 +19,7 @@ import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.api.parallel.Execution
|
||||
import org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT
|
||||
import java.util.UUID
|
||||
import fr.dcproject.entity.Vote as VoteEntity
|
||||
import fr.dcproject.component.vote.entity.Vote as VoteEntity
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@Execution(CONCURRENT)
|
||||
|
||||
Reference in New Issue
Block a user