feature #8: create Vote Article route
This commit is contained in:
@@ -159,6 +159,7 @@ fun Application.module(env: Env = PROD) {
|
|||||||
comment(get())
|
comment(get())
|
||||||
commentArticle(get())
|
commentArticle(get())
|
||||||
commentConstitution(get())
|
commentConstitution(get())
|
||||||
|
voteArticle(get())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import fr.dcproject.repository.Constitution as ConstitutionRepository
|
|||||||
import fr.dcproject.repository.FollowArticle as FollowArticleRepository
|
import fr.dcproject.repository.FollowArticle as FollowArticleRepository
|
||||||
import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository
|
import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository
|
||||||
import fr.dcproject.repository.User as UserRepository
|
import fr.dcproject.repository.User as UserRepository
|
||||||
|
import fr.dcproject.repository.VoteArticle as VoteArticleRepository
|
||||||
|
import fr.dcproject.repository.VoteConstitution as VoteConstitutionRepository
|
||||||
|
|
||||||
val config = Config()
|
val config = Config()
|
||||||
|
|
||||||
@@ -39,6 +41,8 @@ val Module = module {
|
|||||||
single { CommentGenericRepository(get()) }
|
single { CommentGenericRepository(get()) }
|
||||||
single { CommentArticleRepository(get()) }
|
single { CommentArticleRepository(get()) }
|
||||||
single { CommentConstitutionRepository(get()) }
|
single { CommentConstitutionRepository(get()) }
|
||||||
|
single { VoteArticleRepository(get()) }
|
||||||
|
single { VoteConstitutionRepository(get()) }
|
||||||
|
|
||||||
single { Migrations(connection = get(), directory = config.sqlFiles) }
|
single { Migrations(connection = get(), directory = config.sqlFiles) }
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/main/kotlin/fr/dcproject/entity/Vote.kt
Normal file
21
src/main/kotlin/fr/dcproject/entity/Vote.kt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package fr.dcproject.entity
|
||||||
|
|
||||||
|
import fr.postgresjson.entity.EntityUpdatedAt
|
||||||
|
import fr.postgresjson.entity.EntityUpdatedAtImp
|
||||||
|
import fr.postgresjson.entity.UuidEntity
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
open class Vote <T: UuidEntity> (
|
||||||
|
id: UUID = UUID.randomUUID(),
|
||||||
|
createdBy: Citizen,
|
||||||
|
override var target: T,
|
||||||
|
var note: Int,
|
||||||
|
var annonymous: Boolean = true
|
||||||
|
): Extra<T>(id, createdBy),
|
||||||
|
EntityUpdatedAt by EntityUpdatedAtImp() {
|
||||||
|
init {
|
||||||
|
if (note > 1 && note < -1) {
|
||||||
|
error("note must be 1, 0 or -1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/main/kotlin/fr/dcproject/repository/Vote.kt
Normal file
31
src/main/kotlin/fr/dcproject/repository/Vote.kt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package fr.dcproject.repository
|
||||||
|
|
||||||
|
import fr.dcproject.entity.Article
|
||||||
|
import fr.dcproject.entity.Constitution
|
||||||
|
import fr.postgresjson.connexion.Requester
|
||||||
|
import fr.postgresjson.entity.UuidEntity
|
||||||
|
import fr.postgresjson.repository.RepositoryI
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
import fr.dcproject.entity.Vote as VoteEntity
|
||||||
|
|
||||||
|
open class Vote <T: UuidEntity>(override var requester: Requester): RepositoryI<VoteEntity<T>> {
|
||||||
|
override val entityName = VoteEntity::class as KClass<VoteEntity<T>>
|
||||||
|
|
||||||
|
fun vote(vote: VoteEntity<T>) {
|
||||||
|
val reference = vote.target::class.simpleName!!.toLowerCase()
|
||||||
|
val author = vote.createdBy ?: error("vote must be contain an author")
|
||||||
|
val anonymous = author.voteAnnonymous
|
||||||
|
requester
|
||||||
|
.getFunction("vote")
|
||||||
|
.sendQuery(
|
||||||
|
"reference" to reference,
|
||||||
|
"target_id" to vote.target.id,
|
||||||
|
"note" to vote.note,
|
||||||
|
"created_by_id" to author.id,
|
||||||
|
"anonymous" to anonymous
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VoteArticle (requester: Requester): Vote<Article>(requester)
|
||||||
|
class VoteConstitution (requester: Requester): Vote<Constitution>(requester)
|
||||||
37
src/main/kotlin/fr/dcproject/routes/VoteArticle.kt
Normal file
37
src/main/kotlin/fr/dcproject/routes/VoteArticle.kt
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package fr.dcproject.routes
|
||||||
|
|
||||||
|
import fr.dcproject.citizen
|
||||||
|
import fr.dcproject.entity.Citizen
|
||||||
|
import fr.dcproject.routes.VoteArticlePaths.ArticleVoteRequest.Content
|
||||||
|
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.Article as ArticleEntity
|
||||||
|
import fr.dcproject.entity.Vote as VoteEntity
|
||||||
|
import fr.dcproject.repository.VoteArticle as VoteArticleRepository
|
||||||
|
|
||||||
|
@KtorExperimentalLocationsAPI
|
||||||
|
object VoteArticlePaths {
|
||||||
|
@Location("/articles/{article}/vote") class ArticleVoteRequest(val article: ArticleEntity) {
|
||||||
|
data class Content(var note: Int)
|
||||||
|
}
|
||||||
|
@Location("/citizens/{citizen}/votes/articles") class CitizenVoteArticleRequest(val citizen: Citizen)
|
||||||
|
}
|
||||||
|
|
||||||
|
@KtorExperimentalLocationsAPI
|
||||||
|
fun Route.voteArticle(repo: VoteArticleRepository) {
|
||||||
|
put<VoteArticlePaths.ArticleVoteRequest> {
|
||||||
|
val content = call.receive<Content>()
|
||||||
|
repo.vote(VoteEntity(
|
||||||
|
target = it.article,
|
||||||
|
note = content.note,
|
||||||
|
createdBy = this.citizen
|
||||||
|
))
|
||||||
|
call.respond(HttpStatusCode.Created)
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/test/resources/feature/vote.feature
Normal file
21
src/test/resources/feature/vote.feature
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
Feature: vote Article
|
||||||
|
|
||||||
|
Scenario: Vote article
|
||||||
|
Given I am authenticated as John Doe with id "64b7b379-2298-43ec-b428-ba134930cabd"
|
||||||
|
When I send a PUT request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b/vote" with body:
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
"note": 1
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
Then the response status code should be 201
|
||||||
|
|
||||||
|
Scenario: Vote article
|
||||||
|
Given I am authenticated as John Doe with id "64b7b379-2298-43ec-b428-ba134930cabd"
|
||||||
|
When I send a PUT request to "/articles/9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b/vote" with body:
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
"note": -1
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
Then the response status code should be 201
|
||||||
Reference in New Issue
Block a user