diff --git a/build.gradle.kts b/build.gradle.kts
index 36f4c7e..2f95015 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -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)
diff --git a/src/main/kotlin/fr/dcproject/component/comment/article/routes/CreateCommentArticle.kt b/src/main/kotlin/fr/dcproject/component/comment/article/routes/CreateCommentArticle.kt
index fd10799..493f9aa 100644
--- a/src/main/kotlin/fr/dcproject/component/comment/article/routes/CreateCommentArticle.kt
+++ b/src/main/kotlin/fr/dcproject/component/comment/article/routes/CreateCommentArticle.kt
@@ -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::content {
+ minLength(20)
+ maxLength(6000)
+ }
+ }.validate(this)
+ }
}
fun Route.createCommentArticle(repo: CommentArticleRepository, ac: CommentAccessControl) {
post {
mustBeAuth()
- call.receiveOrBadRequest().run {
- CommentForUpdate(
- target = it.article,
- createdBy = citizen,
- content = content
- )
- }.let { comment ->
- ac.assert { canCreate(comment, citizenOrNull) }
- repo.comment(comment)
+ call.receiveOrBadRequest()
+ .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()
+ )
+ }
}
}
}
diff --git a/src/main/resources/openapi.yaml b/src/main/resources/openapi.yaml
index af39955..810cb48 100644
--- a/src/main/resources/openapi.yaml
+++ b/src/main/resources/openapi.yaml
@@ -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}:
diff --git a/src/test/kotlin/integration/Comment articles routes.kt b/src/test/kotlin/integration/Comment articles routes.kt
index 6c7c00e..0962e86 100644
--- a/src/test/kotlin/integration/Comment articles routes.kt
+++ b/src/test/kotlin/integration/Comment articles routes.kt
@@ -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")
}
}
}