feature #8: create Vote Article route

This commit is contained in:
2019-08-30 13:24:37 +02:00
parent 7a8f8d3d6a
commit 1b8a02c2b3
6 changed files with 115 additions and 0 deletions

View File

@@ -159,6 +159,7 @@ fun Application.module(env: Env = PROD) {
comment(get()) comment(get())
commentArticle(get()) commentArticle(get())
commentConstitution(get()) commentConstitution(get())
voteArticle(get())
} }
} }

View File

@@ -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) }
} }

View 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")
}
}
}

View 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)

View 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)
}
}

View 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