From 5ef2345ea61c261035ca977115d57f441fe6ae59 Mon Sep 17 00:00:00 2001 From: Fabrice Lecomte Date: Mon, 22 Mar 2021 02:57:33 +0100 Subject: [PATCH] Test openapi schema of route /opinions/* --- .../opinion/routes/GetCitizenOpinions.kt | 7 +- .../opinion/routes/GetMyOpinionsArticle.kt | 7 +- .../opinion/routes/GetOpinionChoice.kt | 6 +- .../opinion/routes/GetOpinionChoices.kt | 6 +- .../opinion/routes/OpinionArticle.kt | 5 +- .../component/opinion/routes/response.kt | 30 +++ src/main/resources/openapi2.yaml | 192 ++++++++++++++++++ src/test/kotlin/integration/Opinion routes.kt | 2 +- 8 files changed, 249 insertions(+), 6 deletions(-) create mode 100644 src/main/kotlin/fr/dcproject/component/opinion/routes/response.kt diff --git a/src/main/kotlin/fr/dcproject/component/opinion/routes/GetCitizenOpinions.kt b/src/main/kotlin/fr/dcproject/component/opinion/routes/GetCitizenOpinions.kt index 9f7f6b7..f330ce8 100644 --- a/src/main/kotlin/fr/dcproject/component/opinion/routes/GetCitizenOpinions.kt +++ b/src/main/kotlin/fr/dcproject/component/opinion/routes/GetCitizenOpinions.kt @@ -1,5 +1,6 @@ package fr.dcproject.component.opinion.routes +import fr.dcproject.common.response.toOutput import fr.dcproject.common.security.assert import fr.dcproject.common.utils.toUUID import fr.dcproject.component.article.database.ArticleRef @@ -8,6 +9,7 @@ import fr.dcproject.component.citizen.database.CitizenRef import fr.dcproject.component.opinion.OpinionAccessControl import fr.dcproject.component.opinion.database.Opinion 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 @@ -32,7 +34,10 @@ object GetCitizenOpinions { val opinionsEntities: List> = repo.findCitizenOpinionsByTargets(it.citizen, it.id) ac.assert { canView(opinionsEntities, citizenOrNull) } - call.respond(opinionsEntities) + call.respond( + HttpStatusCode.OK, + opinionsEntities.map { it.toOutput() } + ) } } } diff --git a/src/main/kotlin/fr/dcproject/component/opinion/routes/GetMyOpinionsArticle.kt b/src/main/kotlin/fr/dcproject/component/opinion/routes/GetMyOpinionsArticle.kt index e63cca0..bfd7d20 100644 --- a/src/main/kotlin/fr/dcproject/component/opinion/routes/GetMyOpinionsArticle.kt +++ b/src/main/kotlin/fr/dcproject/component/opinion/routes/GetMyOpinionsArticle.kt @@ -1,6 +1,7 @@ package fr.dcproject.component.opinion.routes import fr.dcproject.common.entity.TargetRef +import fr.dcproject.common.response.toOutput import fr.dcproject.common.security.assert import fr.dcproject.component.auth.citizen import fr.dcproject.component.auth.citizenOrNull @@ -11,6 +12,7 @@ import fr.dcproject.routes.PaginatedRequest import fr.dcproject.routes.PaginatedRequestI import fr.postgresjson.connexion.Paginated 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 @@ -37,7 +39,10 @@ object GetMyOpinionsArticle { get { val opinions: Paginated> = repo.findCitizenOpinions(citizen, it.page, it.limit) ac.assert { canView(opinions.result, citizenOrNull) } - call.respond(opinions) + call.respond( + HttpStatusCode.OK, + opinions.toOutput { it.toOutput() } + ) } } } diff --git a/src/main/kotlin/fr/dcproject/component/opinion/routes/GetOpinionChoice.kt b/src/main/kotlin/fr/dcproject/component/opinion/routes/GetOpinionChoice.kt index f7f495c..809b10a 100644 --- a/src/main/kotlin/fr/dcproject/component/opinion/routes/GetOpinionChoice.kt +++ b/src/main/kotlin/fr/dcproject/component/opinion/routes/GetOpinionChoice.kt @@ -7,6 +7,7 @@ import fr.dcproject.component.opinion.database.OpinionChoiceRef import fr.dcproject.component.opinion.database.OpinionChoiceRepository import io.ktor.application.call import io.ktor.features.NotFoundException +import io.ktor.http.HttpStatusCode import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.Location import io.ktor.locations.get @@ -26,7 +27,10 @@ object GetOpinionChoice { val opinionChoice = opinionChoiceRepository.findOpinionChoiceById(it.opinionChoice.id) ?: throw NotFoundException("OpinionChoice ${it.opinionChoice.id} not found") ac.assert { canView(it.opinionChoice, citizenOrNull) } - call.respond(opinionChoice) + call.respond( + HttpStatusCode.OK, + opinionChoice.toOutput() + ) } } } diff --git a/src/main/kotlin/fr/dcproject/component/opinion/routes/GetOpinionChoices.kt b/src/main/kotlin/fr/dcproject/component/opinion/routes/GetOpinionChoices.kt index 6e8f698..e440516 100644 --- a/src/main/kotlin/fr/dcproject/component/opinion/routes/GetOpinionChoices.kt +++ b/src/main/kotlin/fr/dcproject/component/opinion/routes/GetOpinionChoices.kt @@ -5,6 +5,7 @@ import fr.dcproject.component.auth.citizenOrNull import fr.dcproject.component.opinion.OpinionChoiceAccessControl import fr.dcproject.component.opinion.database.OpinionChoiceRepository 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 @@ -21,7 +22,10 @@ object GetOpinionChoices { val opinionChoices = repo.findOpinionsChoices(it.targets) ac.assert { canView(opinionChoices, citizenOrNull) } - call.respond(opinionChoices) + call.respond( + HttpStatusCode.OK, + opinionChoices.map { it.toOutput() } + ) } } } diff --git a/src/main/kotlin/fr/dcproject/component/opinion/routes/OpinionArticle.kt b/src/main/kotlin/fr/dcproject/component/opinion/routes/OpinionArticle.kt index cce198a..4d4d5b9 100644 --- a/src/main/kotlin/fr/dcproject/component/opinion/routes/OpinionArticle.kt +++ b/src/main/kotlin/fr/dcproject/component/opinion/routes/OpinionArticle.kt @@ -44,7 +44,10 @@ object OpinionArticle { ac.assert { canCreate(opinions, citizenOrNull) } repo.updateOpinions(opinions) }.let { - call.respond(HttpStatusCode.Created, it) + call.respond( + HttpStatusCode.Created, + it.map { it.toOutput() } + ) } } } diff --git a/src/main/kotlin/fr/dcproject/component/opinion/routes/response.kt b/src/main/kotlin/fr/dcproject/component/opinion/routes/response.kt new file mode 100644 index 0000000..11147a3 --- /dev/null +++ b/src/main/kotlin/fr/dcproject/component/opinion/routes/response.kt @@ -0,0 +1,30 @@ +package fr.dcproject.component.opinion.routes + +import fr.dcproject.common.response.toOutput +import fr.dcproject.component.opinion.database.Opinion +import fr.dcproject.component.opinion.database.OpinionChoice +import org.joda.time.DateTime +import java.util.UUID + +fun OpinionChoice.toOutput(): Any = this.let { o -> + object { + val id: UUID = o.id + val name: String = o.name + val target: List? = o.target + } +} + +fun Opinion<*>.toOutput(): Any = this.let { o -> + object { + val id: UUID = o.id + val name: String = o.getName() + val target: Any = o.target.let { t -> + val id: UUID = t.id + val reference: String = t.reference + } + val choice: Any = o.choice.toOutput() + val reference: String = o.reference + val createdBy: Any = o.createdBy.toOutput() + val createdAt: DateTime = o.createdAt + } +} diff --git a/src/main/resources/openapi2.yaml b/src/main/resources/openapi2.yaml index 83d6655..93c3c6e 100644 --- a/src/main/resources/openapi2.yaml +++ b/src/main/resources/openapi2.yaml @@ -865,6 +865,137 @@ paths: items: $ref: '#/components/schemas/FollowResponse' + /opinions: + get: + summary: Get all opinions choices + tags: + - opinion + parameters: + - in: query + required: false + name: targets + description: opinion available for defined target + example: + - article + schema: + type: array + items: + type: string + responses: + 200: + description: return + content: + application/json: + schema: + description: Opinion Choice + type: array + items: + $ref: '#/components/schemas/OpinionChoice' + /opinions/{opinion}: + parameters: + - $ref: '#/components/parameters/opinion' + get: + summary: Get one opinion Choices + tags: + - opinion + responses: + 200: + description: return + content: + application/json: + schema: + $ref: '#/components/schemas/OpinionChoice' + + /citizens/{citizen}/opinions: + parameters: + - $ref: '#/components/parameters/citizen' + get: + security: + - JWTAuth: [ ] + summary: Get all opinions of citizen filtered by target ids + tags: + - opinion + - citizen + parameters: + - in: query + required: true + name: id + description: target ids + example: + - 9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b + schema: + type: array + items: + type: string + format: uuid + responses: + 200: + description: Opinions + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Opinion' + /citizens/{citizen}/opinions/articles: + parameters: + - $ref: '#/components/parameters/citizen' + get: + security: + - JWTAuth: [] + summary: Get all opinions of one citizen + tags: + - opinion + - citizen + responses: + 200: + description: Opinions + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/Paginated' + - type: object + properties: + result: + type: array + items: + $ref: '#/components/schemas/Opinion' + + /articles/{article}/opinions: + parameters: + - $ref: '#/components/parameters/article' + put: + security: + - JWTAuth: [] + summary: Add Opinion on one article + tags: + - opinion + - article + requestBody: + content: + application/json: + schema: + type: object + properties: + ids: + type: array + items: + type: string + format: uuid + example: 6e978eb5-3c48-0def-b093-e01f43983adb + responses: + 201: + description: Return the opinion + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Opinion' + 401: + $ref: '#/components/responses/401' + components: parameters: page: @@ -977,6 +1108,16 @@ components: type: string format: uuid + opinion: + in: path + required: true + name: opinion + description: Opinion ID + example: 6e978eb5-3c48-0def-b093-e01f43983adb + schema: + type: string + format: uuid + responses: 401: description: Unautorized @@ -1505,6 +1646,57 @@ components: reference: type: string + OpinionChoice: + description: Opinion Choice + type: object + required: + - name + properties: + id: + type: string + format: uuid + name: + type: string + example: opinion1 + target: + type: array + nullable: true + items: + type: string + description: the name of the target + Opinion: + description: Opinion + type: object + properties: + id: + type: string + format: uuid + name: + type: string + example: opinion1 + target: + type: object + properties: + id: + type: string + format: uuid + reference: + type: string + example: article + choice: + type: object + allOf: + - $ref: '#/components/schemas/OpinionChoice' + reference: + type: string + example: opinion_on_article + createdBy: + $ref: '#/components/schemas/CitizenCreator' + createdAt: + type: string + format: 'date-time' + + securitySchemes: JWTAuth: type: http diff --git a/src/test/kotlin/integration/Opinion routes.kt b/src/test/kotlin/integration/Opinion routes.kt index 580ecc0..7a3815c 100644 --- a/src/test/kotlin/integration/Opinion routes.kt +++ b/src/test/kotlin/integration/Opinion routes.kt @@ -118,7 +118,7 @@ class `Opinion routes` : BaseTest() { } @Test - fun `I can get all opinion of one citizen`() { + fun `I can get all my opinion of one article`() { withIntegrationApplication { `Given I have citizen`("Albert", "Einstein", id = "c1542096-3431-432d-8e35-9dc071d4c818") `Given I have an opinion choice`("Opinion9")