Add validation on route CreateCommentArticle

This commit is contained in:
2021-04-09 00:58:35 +02:00
parent 13cdaaf01a
commit a07b19a3cb
4 changed files with 68 additions and 18 deletions

View File

@@ -332,6 +332,12 @@ tasks.register("testCitizens", Test::class) {
includeTags("citizen")
}
}
tasks.register("testComments", Test::class) {
group = "tests"
useJUnitPlatform {
includeTags("comment")
}
}
dependencyCheck {
formats = listOf(ReportGenerator.Format.HTML, ReportGenerator.Format.XML)

View File

@@ -1,6 +1,6 @@
package fr.dcproject.component.comment.article.routes
import fr.dcproject.common.response.toOutput
import fr.dcproject.application.http.badRequestIfNotValid
import fr.dcproject.common.security.assert
import fr.dcproject.common.utils.receiveOrBadRequest
import fr.dcproject.component.article.database.ArticleRef
@@ -12,6 +12,9 @@ import fr.dcproject.component.comment.article.routes.CreateCommentArticle.PostAr
import fr.dcproject.component.comment.generic.CommentAccessControl
import fr.dcproject.component.comment.generic.database.CommentForUpdate
import fr.dcproject.component.comment.toOutput
import io.konform.validation.Validation
import io.konform.validation.jsonschema.maxLength
import io.konform.validation.jsonschema.minLength
import io.ktor.application.call
import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI
@@ -26,27 +29,36 @@ object CreateCommentArticle {
@Location("/articles/{article}/comments")
class PostArticleCommentRequest(article: UUID) {
val article = ArticleRef(article)
class Input(val content: String)
class Input(val content: String) {
fun validate() = Validation<Input> {
Input::content {
minLength(20)
maxLength(6000)
}
}.validate(this)
}
}
fun Route.createCommentArticle(repo: CommentArticleRepository, ac: CommentAccessControl) {
post<PostArticleCommentRequest> {
mustBeAuth()
call.receiveOrBadRequest<Input>().run {
CommentForUpdate(
target = it.article,
createdBy = citizen,
content = content
)
}.let { comment ->
ac.assert { canCreate(comment, citizenOrNull) }
repo.comment(comment)
call.receiveOrBadRequest<Input>()
.apply { validate().badRequestIfNotValid() }
.run {
CommentForUpdate(
target = it.article,
createdBy = citizen,
content = content
)
}.let { comment ->
ac.assert { canCreate(comment, citizenOrNull) }
repo.comment(comment)
call.respond(
HttpStatusCode.Created,
comment.toOutput()
)
}
call.respond(
HttpStatusCode.Created,
comment.toOutput()
)
}
}
}
}

View File

@@ -563,6 +563,12 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/CommentResponse'
400:
description: BadReqest
content:
application/json:
schema:
$ref: '#/components/schemas/400'
401:
$ref: '#/components/responses/401'
/comments/{comment}:

View File

@@ -1,6 +1,8 @@
package integration
import fr.dcproject.component.citizen.database.CitizenI.Name
import integration.steps.`when`.Validate.ALL
import integration.steps.`when`.Validate.REQUEST_BODY
import integration.steps.`when`.`When I send a GET request`
import integration.steps.`when`.`When I send a POST request`
import integration.steps.`when`.`When I send a PUT request`
@@ -13,6 +15,7 @@ import integration.steps.then.`And the response should contain`
import integration.steps.then.`And the response should not be null`
import integration.steps.then.`Then the response should be`
import integration.steps.then.and
import io.ktor.http.HttpStatusCode.Companion.BadRequest
import io.ktor.http.HttpStatusCode.Companion.Created
import io.ktor.http.HttpStatusCode.Companion.OK
import org.junit.jupiter.api.Tag
@@ -33,14 +36,37 @@ class `Comment articles routes` : BaseTest() {
`with body`(
"""
{
"content": "Hello mister"
"content": "Hello mister MARABOUTCHA"
}
"""
)
} `Then the response should be` Created and {
`And the response should not be null`()
`And the response should contain`("$.target.id", "aa16c635-28da-46f0-9a89-934eef88c7ca")
`And the response should contain`("$.content", "Hello mister")
`And the response should contain`("$.content", "Hello mister MARABOUTCHA")
}
}
}
@Test
@Tag("BadRequest")
fun `I cannot comment article with bad request`() {
withIntegrationApplication {
`Given I have citizen`("Michael", "Faraday")
`Given I have article`(id = "aa16c635-28da-46f0-9a89-934eef88c7ca")
`When I send a POST request`("/articles/aa16c635-28da-46f0-9a89-934eef88c7ca/comments", ALL - REQUEST_BODY) {
`authenticated as`("Michael", "Faraday")
`with body`(
"""
{
"content": "To small content"
}
"""
)
} `Then the response should be` BadRequest and {
`And the response should not be null`()
`And the response should contain`("$.invalidParams[0].name", ".content")
`And the response should contain`("$.invalidParams[0].reason", "must have at least 20 characters")
}
}
}