Test openapi schema of /constitutions/*
This commit is contained in:
@@ -20,6 +20,7 @@ import io.ktor.locations.Location
|
|||||||
import io.ktor.locations.post
|
import io.ktor.locations.post
|
||||||
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
|
||||||
@@ -110,6 +111,23 @@ object CreateConstitution {
|
|||||||
val anonymous: Boolean = c.anonymous
|
val anonymous: Boolean = c.anonymous
|
||||||
val draft: Boolean = c.draft
|
val draft: Boolean = c.draft
|
||||||
val versionId: UUID = c.versionId
|
val versionId: UUID = c.versionId
|
||||||
|
val createdAt: DateTime = c.createdAt
|
||||||
|
val createdBy: Any = c.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package fr.dcproject.component.constitution.routes
|
package fr.dcproject.component.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.constitution.ConstitutionAccessControl
|
import fr.dcproject.component.constitution.ConstitutionAccessControl
|
||||||
@@ -8,11 +9,14 @@ import fr.dcproject.routes.PaginatedRequest
|
|||||||
import fr.dcproject.routes.PaginatedRequestI
|
import fr.dcproject.routes.PaginatedRequestI
|
||||||
import fr.postgresjson.repository.RepositoryI
|
import fr.postgresjson.repository.RepositoryI
|
||||||
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
|
||||||
|
|
||||||
@KtorExperimentalLocationsAPI
|
@KtorExperimentalLocationsAPI
|
||||||
object FindConstitutions {
|
object FindConstitutions {
|
||||||
@@ -29,7 +33,33 @@ object FindConstitutions {
|
|||||||
get<FindConstitutionsRequest> {
|
get<FindConstitutionsRequest> {
|
||||||
val constitutions = repo.find(it.page, it.limit, it.sort, it.direction, it.search)
|
val constitutions = repo.find(it.page, it.limit, it.sort, it.direction, it.search)
|
||||||
ac.assert { canView(constitutions.result, citizenOrNull) }
|
ac.assert { canView(constitutions.result, citizenOrNull) }
|
||||||
call.respond(constitutions)
|
call.respond(
|
||||||
|
HttpStatusCode.OK,
|
||||||
|
constitutions.toOutput { c ->
|
||||||
|
object {
|
||||||
|
val id: UUID = c.id
|
||||||
|
val title: String = c.title
|
||||||
|
val versionId: UUID = c.versionId
|
||||||
|
val createdAt: DateTime = c.createdAt
|
||||||
|
val createdBy: Any = c.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,13 @@ import fr.dcproject.component.constitution.database.ConstitutionRef
|
|||||||
import fr.dcproject.component.constitution.database.ConstitutionRepository
|
import fr.dcproject.component.constitution.database.ConstitutionRepository
|
||||||
import io.ktor.application.call
|
import io.ktor.application.call
|
||||||
import io.ktor.features.NotFoundException
|
import io.ktor.features.NotFoundException
|
||||||
|
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
|
||||||
@@ -25,7 +27,68 @@ object GetConstitution {
|
|||||||
get<GetConstitutionRequest> {
|
get<GetConstitutionRequest> {
|
||||||
val constitution = constitutionRepo.findById(it.constitution.id) ?: throw NotFoundException("Unable to find constitution ${it.constitution.id}")
|
val constitution = constitutionRepo.findById(it.constitution.id) ?: throw NotFoundException("Unable to find constitution ${it.constitution.id}")
|
||||||
ac.assert { canView(constitution, citizenOrNull) }
|
ac.assert { canView(constitution, citizenOrNull) }
|
||||||
call.respond(constitution)
|
call.respond(
|
||||||
|
HttpStatusCode.OK,
|
||||||
|
constitution.let { c ->
|
||||||
|
object {
|
||||||
|
val id: UUID = c.id
|
||||||
|
val title: String = c.title
|
||||||
|
val titles: List<Any> = c.titles.map { t ->
|
||||||
|
object {
|
||||||
|
val id: UUID = t.id
|
||||||
|
val name: String = t.name
|
||||||
|
val rank: Int = t.rank
|
||||||
|
val articles: List<Any> = t.articles.map { a ->
|
||||||
|
val id = a.id
|
||||||
|
val title = a.title
|
||||||
|
val createdBy = a.createdBy.let { cr ->
|
||||||
|
object {
|
||||||
|
val id: UUID = cr.id
|
||||||
|
val name: Any = cr.name.let { n ->
|
||||||
|
object {
|
||||||
|
val firstName: String = n.firstName
|
||||||
|
val lastName: String = n.lastName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val user: Any = cr.user.let { u ->
|
||||||
|
object {
|
||||||
|
val username: String = u.username
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val workgroup: Any? = a.workgroup?.let { w ->
|
||||||
|
object {
|
||||||
|
val id = w.id
|
||||||
|
val name = w.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val anonymous: Boolean = c.anonymous
|
||||||
|
val draft: Boolean = c.draft
|
||||||
|
val versionId: UUID = c.versionId
|
||||||
|
val createdAt: DateTime = c.createdAt
|
||||||
|
val createdBy: Any = c.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -662,6 +662,73 @@ paths:
|
|||||||
401:
|
401:
|
||||||
$ref: '#/components/responses/401'
|
$ref: '#/components/responses/401'
|
||||||
|
|
||||||
|
/constitutions:
|
||||||
|
get:
|
||||||
|
summary: Get all constitutions
|
||||||
|
tags:
|
||||||
|
- constitution
|
||||||
|
operationId: getConstitutions
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/page'
|
||||||
|
- $ref: '#/components/parameters/limit'
|
||||||
|
- $ref: '#/components/parameters/sort'
|
||||||
|
- $ref: '#/components/parameters/direction'
|
||||||
|
- $ref: '#/components/parameters/search'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The Constitution objects
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/Paginated'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
result:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/ConstitutionListingResponse'
|
||||||
|
post:
|
||||||
|
security:
|
||||||
|
- JWTAuth: [ ]
|
||||||
|
summary: Create new Constitution
|
||||||
|
tags:
|
||||||
|
- constitution
|
||||||
|
operationId: insertConstitution
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ConstitutionRequest'
|
||||||
|
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
description: Constitution created
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ConstitutionResponse'
|
||||||
|
401:
|
||||||
|
$ref: '#/components/responses/401'
|
||||||
|
400:
|
||||||
|
$ref: '#/components/responses/400'
|
||||||
|
/constitutions/{constitution}:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/constitution'
|
||||||
|
get:
|
||||||
|
summary: Get all constitutions
|
||||||
|
tags:
|
||||||
|
- constitution
|
||||||
|
operationId: getConstitutions
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The Constitution objects
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ConstitutionResponse'
|
||||||
|
|
||||||
components:
|
components:
|
||||||
parameters:
|
parameters:
|
||||||
page:
|
page:
|
||||||
@@ -781,6 +848,12 @@ components:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
description: noting
|
description: noting
|
||||||
|
400:
|
||||||
|
description: BadReqest
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
description: noting
|
||||||
|
|
||||||
schemas:
|
schemas:
|
||||||
UUID:
|
UUID:
|
||||||
@@ -962,6 +1035,9 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
nullable: true
|
nullable: true
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- name
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
type: string
|
type: string
|
||||||
@@ -1139,6 +1215,136 @@ components:
|
|||||||
minimum: 0
|
minimum: 0
|
||||||
score:
|
score:
|
||||||
type: number
|
type: number
|
||||||
|
ConstitutionRequest:
|
||||||
|
additionalProperties: false
|
||||||
|
description: The versionId field must be defined for update contitution
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- title
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: '#/components/schemas/UUID'
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
example:
|
||||||
|
Constitution for the liberty
|
||||||
|
titles:
|
||||||
|
type: array
|
||||||
|
default: [ ]
|
||||||
|
items:
|
||||||
|
additionalProperties: false
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: '#/components/schemas/UUID'
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example:
|
||||||
|
The liberties
|
||||||
|
articles:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: '#/components/schemas/UUID'
|
||||||
|
anonymous:
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
draft:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
versionId:
|
||||||
|
$ref: '#/components/schemas/UUID'
|
||||||
|
ConstitutionResponse:
|
||||||
|
additionalProperties: false
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- title
|
||||||
|
- titles
|
||||||
|
- anonymous
|
||||||
|
- draft
|
||||||
|
- versionId
|
||||||
|
- createdBy
|
||||||
|
- createdAt
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: '#/components/schemas/UUID'
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
example:
|
||||||
|
Constitution for the liberty
|
||||||
|
titles:
|
||||||
|
type: array
|
||||||
|
default: [ ]
|
||||||
|
items:
|
||||||
|
additionalProperties: false
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- name
|
||||||
|
- rank
|
||||||
|
- articles
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: '#/components/schemas/UUID'
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example:
|
||||||
|
The liberties
|
||||||
|
rank:
|
||||||
|
type: integer
|
||||||
|
minimum: 0
|
||||||
|
example: 0
|
||||||
|
createdBy:
|
||||||
|
$ref: '#/components/schemas/CitizenCreator'
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
format: 'date-time'
|
||||||
|
articles:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/ArticleListingResponse'
|
||||||
|
anonymous:
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
draft:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
versionId:
|
||||||
|
$ref: '#/components/schemas/UUID'
|
||||||
|
createdBy:
|
||||||
|
$ref: '#/components/schemas/CitizenCreator'
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
format: 'date-time'
|
||||||
|
ConstitutionListingResponse:
|
||||||
|
additionalProperties: false
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- title
|
||||||
|
- versionId
|
||||||
|
- createdAt
|
||||||
|
- createdBy
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: '#/components/schemas/UUID'
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
example:
|
||||||
|
Constitution for the liberty
|
||||||
|
versionId:
|
||||||
|
$ref: '#/components/schemas/UUID'
|
||||||
|
createdBy:
|
||||||
|
$ref: '#/components/schemas/CitizenCreator'
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
format: 'date-time'
|
||||||
|
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
JWTAuth:
|
JWTAuth:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package integration
|
package integration
|
||||||
|
|
||||||
|
import integration.steps.`when`.Validate
|
||||||
import integration.steps.then.`And have property`
|
import integration.steps.then.`And have property`
|
||||||
import integration.steps.then.`And the response should not be null`
|
import integration.steps.then.`And the response should not be null`
|
||||||
import integration.steps.then.`Then the response should be`
|
import integration.steps.then.`Then the response should be`
|
||||||
@@ -12,6 +13,8 @@ import integration.steps.given.`Given I have citizen`
|
|||||||
import integration.steps.given.`Given I have constitution`
|
import integration.steps.given.`Given I have constitution`
|
||||||
import integration.steps.given.`Given I have constitutions`
|
import integration.steps.given.`Given I have constitutions`
|
||||||
import integration.steps.given.`authenticated as`
|
import integration.steps.given.`authenticated as`
|
||||||
|
import io.ktor.http.HttpStatusCode.Companion.BadRequest
|
||||||
|
import io.ktor.http.HttpStatusCode.Companion.Created
|
||||||
import io.ktor.http.HttpStatusCode.Companion.OK
|
import io.ktor.http.HttpStatusCode.Companion.OK
|
||||||
import org.junit.jupiter.api.Tag
|
import org.junit.jupiter.api.Tag
|
||||||
import org.junit.jupiter.api.Tags
|
import org.junit.jupiter.api.Tags
|
||||||
@@ -70,17 +73,39 @@ class `Constitution routes` : BaseTest() {
|
|||||||
"anonymous":true,
|
"anonymous":true,
|
||||||
"titles":[
|
"titles":[
|
||||||
{
|
{
|
||||||
"name":"plop",
|
"name":"plop"
|
||||||
"rank":0
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
} `Then the response should be` OK and {
|
} `Then the response should be` Created and {
|
||||||
`And the response should not be null`()
|
`And the response should not be null`()
|
||||||
`And have property`("$.versionId") `whish contains` "15814bb6-8d90-4c6a-a456-c3939a8ec75e"
|
`And have property`("$.versionId") `whish contains` "15814bb6-8d90-4c6a-a456-c3939a8ec75e"
|
||||||
`And have property`("$.title") `whish contains` "Hello world!"
|
`And have property`("$.title") `whish contains` "Hello world!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `I cannot create an constitution if bad request`() {
|
||||||
|
withIntegrationApplication {
|
||||||
|
`Given I have citizen`("Henri", "Poincaré")
|
||||||
|
`When I send a POST request`("/constitutions", Validate.ALL - Validate.REQUEST_BODY) {
|
||||||
|
`authenticated as`("Henri", "Poincaré")
|
||||||
|
`with body`("""
|
||||||
|
{
|
||||||
|
"versionId":"15814bb6-8d90-4c6a-a456-c3939a8ec75e",
|
||||||
|
"title":"Hello world!",
|
||||||
|
"anonymous":true,
|
||||||
|
"titles":[
|
||||||
|
{
|
||||||
|
"name":"plop",
|
||||||
|
"wrongField":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
} `Then the response should be` BadRequest
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user