From 78a6cc417c0ee24fc7e2cdc3d6ce532143cea703 Mon Sep 17 00:00:00 2001 From: Fabrice Lecomte Date: Wed, 17 Mar 2021 22:07:14 +0100 Subject: [PATCH] Test openapi schema of POST/GET /constitutions/{constitution}/comments GET /citizens/{citizen}/comments/constitutions --- .../routes/CreateConstitutionComment.kt | 68 +++++++++++++--- .../routes/GetCitizenCommentConstitution.kt | 52 +++++++++++- .../routes/GetConstitutionComment.kt | 51 +++++++++++- src/main/resources/openapi2.yaml | 79 +++++++++++++++++++ 4 files changed, 238 insertions(+), 12 deletions(-) diff --git a/src/main/kotlin/fr/dcproject/component/comment/constitution/routes/CreateConstitutionComment.kt b/src/main/kotlin/fr/dcproject/component/comment/constitution/routes/CreateConstitutionComment.kt index 17e7cec..9752cf4 100644 --- a/src/main/kotlin/fr/dcproject/component/comment/constitution/routes/CreateConstitutionComment.kt +++ b/src/main/kotlin/fr/dcproject/component/comment/constitution/routes/CreateConstitutionComment.kt @@ -1,9 +1,11 @@ package fr.dcproject.component.comment.constitution.routes import fr.dcproject.common.security.assert +import fr.dcproject.common.utils.receiveOrBadRequest import fr.dcproject.component.auth.citizen import fr.dcproject.component.auth.citizenOrNull import fr.dcproject.component.comment.constitution.database.CommentConstitutionRepository +import fr.dcproject.component.comment.constitution.routes.CreateConstitutionComment.CreateConstitutionCommentRequest.Input import fr.dcproject.component.comment.generic.CommentAccessControl import fr.dcproject.component.comment.generic.database.CommentForUpdate import fr.dcproject.component.constitution.database.ConstitutionRef @@ -12,9 +14,9 @@ import io.ktor.http.HttpStatusCode import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.Location import io.ktor.locations.post -import io.ktor.request.receiveText import io.ktor.response.respond import io.ktor.routing.Route +import org.joda.time.DateTime import java.util.UUID @KtorExperimentalLocationsAPI @@ -22,20 +24,66 @@ object CreateConstitutionComment { @Location("/constitutions/{constitution}/comments") class CreateConstitutionCommentRequest(constitution: UUID) { val constitution = ConstitutionRef(constitution) + class Input(val content: String) } fun Route.createConstitutionComment(repo: CommentConstitutionRepository, ac: CommentAccessControl) { post { - val content = call.receiveText() - val comment = CommentForUpdate( - target = it.constitution, - createdBy = citizen, - content = content - ) - ac.assert { canCreate(comment, citizenOrNull) } - repo.comment(comment) + call.receiveOrBadRequest().run { + CommentForUpdate( + target = it.constitution, + createdBy = citizen, + content = content + ) + }.let { comment -> + ac.assert { canCreate(comment, citizenOrNull) } + repo.comment(comment) - call.respond(HttpStatusCode.Created, comment) + call.respond( + HttpStatusCode.Created, + object { + val id: UUID = comment.id + val content: String = comment.content + val childrenCount: Int = 0 + val createdAt: DateTime = comment.createdAt + val parent: Any? = comment.parent?.let { p -> + object { + val id: UUID = p.id + val reference: String = p.reference + } + } + val target: Any = comment.target.let { t -> + object { + val id: UUID = t.id + val reference: String = t.reference + } + } + val createdBy: Any = comment.createdBy.let { c -> + object { + val id: UUID = c.id + val name: Any = c.name.let { n -> + object { + val firstName: String = n.firstName + val lastName: String = n.lastName + } + } + val user: Any = c.user.let { u -> + object { + val username: String = u.username + } + } + } + } + val votes: Any = object { + val up: Int = 0 + val neutral: Int = 0 + val down: Int = 0 + val total: Int = 0 + val score: Int = 0 + } + } + ) + } } } } diff --git a/src/main/kotlin/fr/dcproject/component/comment/constitution/routes/GetCitizenCommentConstitution.kt b/src/main/kotlin/fr/dcproject/component/comment/constitution/routes/GetCitizenCommentConstitution.kt index e81047f..9305892 100644 --- a/src/main/kotlin/fr/dcproject/component/comment/constitution/routes/GetCitizenCommentConstitution.kt +++ b/src/main/kotlin/fr/dcproject/component/comment/constitution/routes/GetCitizenCommentConstitution.kt @@ -1,16 +1,19 @@ package fr.dcproject.component.comment.constitution.routes +import fr.dcproject.common.dto.toOutput import fr.dcproject.common.security.assert import fr.dcproject.component.auth.citizenOrNull import fr.dcproject.component.citizen.database.CitizenRef import fr.dcproject.component.comment.constitution.database.CommentConstitutionRepository import fr.dcproject.component.comment.generic.CommentAccessControl 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.response.respond import io.ktor.routing.Route +import org.joda.time.DateTime import java.util.UUID @KtorExperimentalLocationsAPI @@ -24,7 +27,54 @@ object GetCitizenCommentConstitution { get { val comments = repo.findByCitizen(it.citizen) ac.assert { canView(comments.result, citizenOrNull) } - call.respond(comments) + call.respond( + HttpStatusCode.OK, + comments.toOutput { comment -> + object { + val id: UUID = comment.id + val content: String = comment.content + val childrenCount: Int = comment.childrenCount ?: 0 + val createdAt: DateTime = comment.createdAt + val parent: Any? = comment.parent?.let { p -> + object { + val id: UUID = p.id + val reference: String = p.reference + } + } + val target: Any = comment.target.let { t -> + object { + val id: UUID = t.id + val reference: String = t.reference + } + } + val createdBy: Any = comment.createdBy.let { c -> + object { + val id: UUID = c.id + val name: Any = c.name.let { n -> + object { + val firstName: String = n.firstName + val lastName: String = n.lastName + } + } + val user: Any = c.user.let { u -> + object { + val username: String = u.username + } + } + } + } + val votes: Any = comment.votes.let { v -> + object { + val up: Int = v.up + val neutral: Int = v.neutral + val down: Int = v.down + val total: Int = v.total + val score: Int = v.score + } + } + } + } + ) } } } diff --git a/src/main/kotlin/fr/dcproject/component/comment/constitution/routes/GetConstitutionComment.kt b/src/main/kotlin/fr/dcproject/component/comment/constitution/routes/GetConstitutionComment.kt index 460fcd9..e17b527 100644 --- a/src/main/kotlin/fr/dcproject/component/comment/constitution/routes/GetConstitutionComment.kt +++ b/src/main/kotlin/fr/dcproject/component/comment/constitution/routes/GetConstitutionComment.kt @@ -1,5 +1,6 @@ package fr.dcproject.component.comment.constitution.routes +import fr.dcproject.common.dto.toOutput import fr.dcproject.common.security.assert import fr.dcproject.component.auth.citizenOrNull import fr.dcproject.component.comment.constitution.database.CommentConstitutionRepository @@ -12,6 +13,7 @@ import io.ktor.locations.Location import io.ktor.locations.get import io.ktor.response.respond import io.ktor.routing.Route +import org.joda.time.DateTime import java.util.UUID @KtorExperimentalLocationsAPI @@ -25,7 +27,54 @@ object GetConstitutionComment { get { val comments = repo.findByTarget(it.constitution) ac.assert { canView(comments.result, citizenOrNull) } - call.respond(HttpStatusCode.OK, comments) + call.respond( + HttpStatusCode.OK, + comments.toOutput { comment -> + object { + val id: UUID = comment.id + val content: String = comment.content + val childrenCount: Int = comment.childrenCount ?: 0 + val createdAt: DateTime = comment.createdAt + val parent: Any? = comment.parent?.let { p -> + object { + val id: UUID = p.id + val reference: String = p.reference + } + } + val target: Any = comment.target.let { t -> + object { + val id: UUID = t.id + val reference: String = t.reference + } + } + val createdBy: Any = comment.createdBy.let { c -> + object { + val id: UUID = c.id + val name: Any = c.name.let { n -> + object { + val firstName: String = n.firstName + val lastName: String = n.lastName + } + } + val user: Any = c.user.let { u -> + object { + val username: String = u.username + } + } + } + } + val votes: Any = comment.votes.let { v -> + object { + val up: Int = v.up + val neutral: Int = v.neutral + val down: Int = v.down + val total: Int = v.total + val score: Int = v.score + } + } + } + } + ) } } } diff --git a/src/main/resources/openapi2.yaml b/src/main/resources/openapi2.yaml index e692426..6a8d79c 100644 --- a/src/main/resources/openapi2.yaml +++ b/src/main/resources/openapi2.yaml @@ -621,6 +621,75 @@ paths: $ref: '#/components/schemas/CommentResponse' 401: $ref: '#/components/responses/401' + /citizens/{citizen}/comments/constitutions: + parameters: + - $ref: '#/components/parameters/citizen' + get: + security: + - JWTAuth: [] + summary: all constitution comments for one citizen + tags: + - comment + - constitution + - citizen + responses: + 200: + description: Comments + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/Paginated' + - type: object + properties: + result: + type: array + items: + $ref: '#/components/schemas/CommentResponse' + 401: + $ref: '#/components/responses/401' + /constitutions/{constitution}/comments: + parameters: + - $ref: '#/components/parameters/constitution' + get: + summary: Get comment and children of one constitution + tags: + - comment + - constitution + responses: + 200: + description: Return Comment and children + content: + application/json: + schema: + $ref: '#/components/schemas/CommentResponse' + post: + security: + - JWTAuth: [] + summary: Create Comment to constitution + tags: + - comment + - constitution + requestBody: + content: + application/json: + schema: + required: + - content + properties: + content: + type: string + example: + Lorem ipsum... + responses: + 201: + description: Return created comment + content: + application/json: + schema: + $ref: '#/components/schemas/CommentResponse' + 401: + $ref: '#/components/responses/401' components: parameters: @@ -724,6 +793,16 @@ components: type: string format: uuid + constitution: + name: constitution + in: path + required: true + description: the ID of constitution + example: e74be8e4-6823-47c4-bd1b-789725b2fa8e + schema: + type: string + format: uuid + responses: 401: description: Unautorized