From f20964878f3d9c15968d1c40ab3cb2e4222ff5c7 Mon Sep 17 00:00:00 2001 From: Fabrice Lecomte Date: Mon, 7 Oct 2019 14:15:43 +0200 Subject: [PATCH] Improve Vote Comment Add "targetReference" field into Extra Entity Add VoteCommentRoute to OpenApi --- src/main/kotlin/fr/dcproject/Module.kt | 4 +-- .../kotlin/fr/dcproject/entity/Comment.kt | 4 +-- src/main/kotlin/fr/dcproject/entity/Extra.kt | 5 +++- src/main/kotlin/fr/dcproject/entity/Follow.kt | 4 +-- src/main/kotlin/fr/dcproject/entity/Vote.kt | 4 +-- .../kotlin/fr/dcproject/repository/Comment.kt | 8 ++---- .../kotlin/fr/dcproject/repository/Vote.kt | 17 ++++++++++- .../kotlin/fr/dcproject/routes/VoteArticle.kt | 16 +++++------ src/main/resources/openApi.yaml | 28 +++++++++++++++++++ src/test/resources/feature/vote.feature | 4 ++- 10 files changed, 70 insertions(+), 24 deletions(-) diff --git a/src/main/kotlin/fr/dcproject/Module.kt b/src/main/kotlin/fr/dcproject/Module.kt index 92338dd..0e99e72 100644 --- a/src/main/kotlin/fr/dcproject/Module.kt +++ b/src/main/kotlin/fr/dcproject/Module.kt @@ -15,7 +15,7 @@ import fr.dcproject.repository.FollowArticle as FollowArticleRepository import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository import fr.dcproject.repository.User as UserRepository import fr.dcproject.repository.VoteArticle as VoteArticleRepository -import fr.dcproject.repository.VoteArticleComment as VoteArticleCommentRepository +import fr.dcproject.repository.VoteComment as VoteCommentRepository import fr.dcproject.repository.VoteConstitution as VoteConstitutionRepository val config = Config() @@ -44,7 +44,7 @@ val Module = module { single { CommentConstitutionRepository(get()) } single { VoteArticleRepository(get()) } single { VoteConstitutionRepository(get()) } - single { VoteArticleCommentRepository(get()) } + single { VoteCommentRepository(get()) } single { Migrations(connection = get(), directory = config.sqlFiles) } } diff --git a/src/main/kotlin/fr/dcproject/entity/Comment.kt b/src/main/kotlin/fr/dcproject/entity/Comment.kt index ca94e69..4d5a2a6 100644 --- a/src/main/kotlin/fr/dcproject/entity/Comment.kt +++ b/src/main/kotlin/fr/dcproject/entity/Comment.kt @@ -6,12 +6,12 @@ import java.util.* open class Comment ( id: UUID = UUID.randomUUID(), createdBy: Citizen, - override var target: T, + target: T, var content: String, var responses: List>? = null, var parent: Comment? = null, var parentsIds: List? = null, val childrenCount: Int? = null -): Extra(id, createdBy), +): Extra(id, createdBy, target), EntityUpdatedAt by EntityUpdatedAtImp(), EntityDeletedAt by EntityDeletedAtImp() diff --git a/src/main/kotlin/fr/dcproject/entity/Extra.kt b/src/main/kotlin/fr/dcproject/entity/Extra.kt index 0540c99..afac3d5 100644 --- a/src/main/kotlin/fr/dcproject/entity/Extra.kt +++ b/src/main/kotlin/fr/dcproject/entity/Extra.kt @@ -8,11 +8,14 @@ interface ExtraI : EntityCreatedAt, EntityCreatedBy{ var target: T + var targetReference: String } abstract class Extra( id: UUID? = UUID.randomUUID(), - createdBy: Citizen + createdBy: Citizen, + override var target: T, + override var targetReference: String = target::class.simpleName!!.toLowerCase() ): ExtraI, UuidEntity(id), diff --git a/src/main/kotlin/fr/dcproject/entity/Follow.kt b/src/main/kotlin/fr/dcproject/entity/Follow.kt index 69ed3f2..7cb413e 100644 --- a/src/main/kotlin/fr/dcproject/entity/Follow.kt +++ b/src/main/kotlin/fr/dcproject/entity/Follow.kt @@ -5,5 +5,5 @@ import java.util.* class Follow ( id: UUID = UUID.randomUUID(), createdBy: Citizen, - override var target: T -): Extra(id, createdBy) + target: T +): Extra(id, createdBy, target) diff --git a/src/main/kotlin/fr/dcproject/entity/Vote.kt b/src/main/kotlin/fr/dcproject/entity/Vote.kt index 63844d6..e27db8a 100644 --- a/src/main/kotlin/fr/dcproject/entity/Vote.kt +++ b/src/main/kotlin/fr/dcproject/entity/Vote.kt @@ -8,10 +8,10 @@ import java.util.* open class Vote ( id: UUID = UUID.randomUUID(), createdBy: Citizen, - override var target: T, + target: T, var note: Int, var anonymous: Boolean = true -): Extra(id, createdBy), +): Extra(id, createdBy, target), EntityUpdatedAt by EntityUpdatedAtImp() { init { if (note > 1 && note < -1) { diff --git a/src/main/kotlin/fr/dcproject/repository/Comment.kt b/src/main/kotlin/fr/dcproject/repository/Comment.kt index fe36c09..8c24e43 100644 --- a/src/main/kotlin/fr/dcproject/repository/Comment.kt +++ b/src/main/kotlin/fr/dcproject/repository/Comment.kt @@ -84,10 +84,8 @@ abstract class Comment (override var requester: Requester): Repos } } -class GenericTargetEntity(id: UUID = UUID.randomUUID()): UuidEntity(id) - -class CommentGeneric (requester: Requester): Comment(requester) { - override fun findById(id: UUID): CommentEntity? { +class CommentGeneric (requester: Requester): Comment(requester) { + override fun findById(id: UUID): CommentEntity? { return requester .getFunction("find_comment_by_id") .selectOne(mapOf("id" to id)) @@ -97,7 +95,7 @@ class CommentGeneric (requester: Requester): Comment(reques citizen: CitizenEntity, page: Int, limit: Int - ): Paginated> { + ): Paginated> { return requester.run { getFunction("find_comments_by_citizen") .select(page, limit, diff --git a/src/main/kotlin/fr/dcproject/repository/Vote.kt b/src/main/kotlin/fr/dcproject/repository/Vote.kt index 16081a6..d8b487f 100644 --- a/src/main/kotlin/fr/dcproject/repository/Vote.kt +++ b/src/main/kotlin/fr/dcproject/repository/Vote.kt @@ -22,7 +22,7 @@ open class Vote (override var requester: Requester): RepositoryI< val reference = if (target is Comment<*>) { target::class.simpleName!!.toLowerCase() + "_on_" + - target.target::class.simpleName!!.toLowerCase() + target.targetReference } else { target::class.simpleName!!.toLowerCase() } @@ -101,6 +101,21 @@ class VoteArticleComment (requester: Requester): Vote>(requeste ) } +class VoteComment (requester: Requester): Vote>(requester) { + fun findByCitizen( + citizen: CitizenEntity, + page: Int = 1, + limit: Int = 50 + ): Paginated>> = + findByCitizen( + citizen.id ?: error("The citizen must have an id"), + "article", + object: TypeReference>>>() {}, + page, + limit + ) +} + class VoteConstitution (requester: Requester): Vote(requester) { fun findByCitizen( citizen: CitizenEntity, diff --git a/src/main/kotlin/fr/dcproject/routes/VoteArticle.kt b/src/main/kotlin/fr/dcproject/routes/VoteArticle.kt index a9bd41b..e0818a7 100644 --- a/src/main/kotlin/fr/dcproject/routes/VoteArticle.kt +++ b/src/main/kotlin/fr/dcproject/routes/VoteArticle.kt @@ -2,10 +2,10 @@ package fr.dcproject.routes import fr.dcproject.citizen import fr.dcproject.entity.Citizen -import fr.dcproject.repository.CommentArticle -import fr.dcproject.repository.VoteArticleComment -import fr.dcproject.routes.VoteArticlePaths.ArticleCommentVoteRequest +import fr.dcproject.repository.CommentGeneric +import fr.dcproject.repository.VoteComment import fr.dcproject.routes.VoteArticlePaths.ArticleVoteRequest +import fr.dcproject.routes.VoteArticlePaths.CommentVoteRequest import fr.dcproject.security.voter.VoteVoter.Action.CREATE import fr.dcproject.security.voter.VoteVoter.Action.VIEW import fr.dcproject.security.voter.assertCan @@ -30,8 +30,8 @@ object VoteArticlePaths { data class Content(var note: Int) } - @Location("/articles/{article}/comments/{comment}/vote") - class ArticleCommentVoteRequest(val article: ArticleEntity, val comment: UUID) { + @Location("/comments/{comment}/vote") + class CommentVoteRequest(val comment: UUID) { data class Content(var note: Int) } @@ -53,7 +53,7 @@ object VoteArticlePaths { } @KtorExperimentalLocationsAPI -fun Route.voteArticle(repo: VoteArticleRepository, voteCommentRepo: VoteArticleComment, commentRepo: CommentArticle) { +fun Route.voteArticle(repo: VoteArticleRepository, voteCommentRepo: VoteComment, commentRepo: CommentGeneric) { put { val content = call.receive() val vote = VoteEntity( @@ -66,9 +66,9 @@ fun Route.voteArticle(repo: VoteArticleRepository, voteCommentRepo: VoteArticleC call.respond(HttpStatusCode.Created, votes) } - put { + put { val comment = commentRepo.findById(it.comment)!! - val content = call.receive() + val content = call.receive() val vote = VoteEntity( target = comment, note = content.note, diff --git a/src/main/resources/openApi.yaml b/src/main/resources/openApi.yaml index 6d27230..3f163d6 100644 --- a/src/main/resources/openApi.yaml +++ b/src/main/resources/openApi.yaml @@ -405,6 +405,7 @@ paths: application/json: schema: $ref: '#/components/schemas/CommentResponse' + /articles/{article}/follows: parameters: - $ref: '#/components/parameters/article' @@ -451,6 +452,7 @@ paths: responses: 204: description: Return only http status 204 on success + /articles/{article}/vote: parameters: - $ref: '#/components/parameters/article' @@ -492,6 +494,31 @@ paths: responses: 201: description: Return only http status 201 on success + /comments/{comment}/vote: + parameters: + - $ref: '#/components/parameters/comment' + put: + security: + - JWTAuth: [] + summary: Vote for a comment + tags: + - vote + - comment + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/VoteRequest' + responses: + 201: + description: Return votes aggregation + content: + application/json: + schema: + $ref: '#/components/schemas/VoteAggregation' + 404: + description: article or comment not found + /citizens/{citizen}/votes/articles: parameters: @@ -584,6 +611,7 @@ components: in: path required: true description: the ID of article + example: d91aa0cd-61d6-83cc-41bb-8d5656e130f7 schema: type: string format: uuid diff --git a/src/test/resources/feature/vote.feature b/src/test/resources/feature/vote.feature index bd1360b..292420c 100644 --- a/src/test/resources/feature/vote.feature +++ b/src/test/resources/feature/vote.feature @@ -40,10 +40,12 @@ Feature: vote Article Scenario: Can vote a comment on article Given I am authenticated as John Doe with id "64b7b379-2298-43ec-b428-ba134930cabd" And I have comment "ea5c9e87-c99e-4646-a381-2910219e077f" on article "cc9c624e-a27e-42de-af78-ae821c657a68" - When I send a PUT request to "/articles/cc9c624e-a27e-42de-af78-ae821c657a68/comments/ea5c9e87-c99e-4646-a381-2910219e077f/vote" with body: + When I send a PUT request to "/comments/ea5c9e87-c99e-4646-a381-2910219e077f/vote" with body: """ { "note": -1 } """ Then the response status code should be 201 + And the response should contain object: + | down | 1 |