Test openapi schema of

POST/GET /constitutions/{constitution}/comments
GET /citizens/{citizen}/comments/constitutions
This commit is contained in:
2021-03-17 22:07:14 +01:00
parent 564d612e9a
commit 78a6cc417c
4 changed files with 238 additions and 12 deletions

View File

@@ -1,9 +1,11 @@
package fr.dcproject.component.comment.constitution.routes package fr.dcproject.component.comment.constitution.routes
import fr.dcproject.common.security.assert import fr.dcproject.common.security.assert
import fr.dcproject.common.utils.receiveOrBadRequest
import fr.dcproject.component.auth.citizen import fr.dcproject.component.auth.citizen
import fr.dcproject.component.auth.citizenOrNull import fr.dcproject.component.auth.citizenOrNull
import fr.dcproject.component.comment.constitution.database.CommentConstitutionRepository 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.CommentAccessControl
import fr.dcproject.component.comment.generic.database.CommentForUpdate import fr.dcproject.component.comment.generic.database.CommentForUpdate
import fr.dcproject.component.constitution.database.ConstitutionRef 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.KtorExperimentalLocationsAPI
import io.ktor.locations.Location import io.ktor.locations.Location
import io.ktor.locations.post import io.ktor.locations.post
import io.ktor.request.receiveText
import io.ktor.response.respond import io.ktor.response.respond
import io.ktor.routing.Route import io.ktor.routing.Route
import org.joda.time.DateTime
import java.util.UUID import java.util.UUID
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@@ -22,20 +24,66 @@ object CreateConstitutionComment {
@Location("/constitutions/{constitution}/comments") @Location("/constitutions/{constitution}/comments")
class CreateConstitutionCommentRequest(constitution: UUID) { class CreateConstitutionCommentRequest(constitution: UUID) {
val constitution = ConstitutionRef(constitution) val constitution = ConstitutionRef(constitution)
class Input(val content: String)
} }
fun Route.createConstitutionComment(repo: CommentConstitutionRepository, ac: CommentAccessControl) { fun Route.createConstitutionComment(repo: CommentConstitutionRepository, ac: CommentAccessControl) {
post<CreateConstitutionCommentRequest> { post<CreateConstitutionCommentRequest> {
val content = call.receiveText() call.receiveOrBadRequest<Input>().run {
val comment = CommentForUpdate( CommentForUpdate(
target = it.constitution, target = it.constitution,
createdBy = citizen, createdBy = citizen,
content = content content = content
) )
ac.assert { canCreate(comment, citizenOrNull) } }.let { comment ->
repo.comment(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
}
}
)
}
} }
} }
} }

View File

@@ -1,16 +1,19 @@
package fr.dcproject.component.comment.constitution.routes package fr.dcproject.component.comment.constitution.routes
import fr.dcproject.common.dto.toOutput
import fr.dcproject.common.security.assert import fr.dcproject.common.security.assert
import fr.dcproject.component.auth.citizenOrNull import fr.dcproject.component.auth.citizenOrNull
import fr.dcproject.component.citizen.database.CitizenRef import fr.dcproject.component.citizen.database.CitizenRef
import fr.dcproject.component.comment.constitution.database.CommentConstitutionRepository import fr.dcproject.component.comment.constitution.database.CommentConstitutionRepository
import fr.dcproject.component.comment.generic.CommentAccessControl import fr.dcproject.component.comment.generic.CommentAccessControl
import io.ktor.application.call import io.ktor.application.call
import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location import io.ktor.locations.Location
import io.ktor.locations.get import io.ktor.locations.get
import io.ktor.response.respond import io.ktor.response.respond
import io.ktor.routing.Route import io.ktor.routing.Route
import org.joda.time.DateTime
import java.util.UUID import java.util.UUID
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@@ -24,7 +27,54 @@ object GetCitizenCommentConstitution {
get<GetCitizenCommentConstitutionRequest> { get<GetCitizenCommentConstitutionRequest> {
val comments = repo.findByCitizen(it.citizen) val comments = repo.findByCitizen(it.citizen)
ac.assert { canView(comments.result, citizenOrNull) } 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
}
}
}
}
)
} }
} }
} }

View File

@@ -1,5 +1,6 @@
package fr.dcproject.component.comment.constitution.routes package fr.dcproject.component.comment.constitution.routes
import fr.dcproject.common.dto.toOutput
import fr.dcproject.common.security.assert import fr.dcproject.common.security.assert
import fr.dcproject.component.auth.citizenOrNull import fr.dcproject.component.auth.citizenOrNull
import fr.dcproject.component.comment.constitution.database.CommentConstitutionRepository 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.locations.get
import io.ktor.response.respond import io.ktor.response.respond
import io.ktor.routing.Route import io.ktor.routing.Route
import org.joda.time.DateTime
import java.util.UUID import java.util.UUID
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@@ -25,7 +27,54 @@ object GetConstitutionComment {
get<GetConstitutionCommentRequest> { get<GetConstitutionCommentRequest> {
val comments = repo.findByTarget(it.constitution) val comments = repo.findByTarget(it.constitution)
ac.assert { canView(comments.result, citizenOrNull) } 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
}
}
}
}
)
} }
} }
} }

View File

@@ -621,6 +621,75 @@ paths:
$ref: '#/components/schemas/CommentResponse' $ref: '#/components/schemas/CommentResponse'
401: 401:
$ref: '#/components/responses/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: components:
parameters: parameters:
@@ -724,6 +793,16 @@ components:
type: string type: string
format: uuid 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: responses:
401: 401:
description: Unautorized description: Unautorized