Move Comment article to a Component

This commit is contained in:
2021-01-17 00:05:37 +01:00
parent b61fc3c7d1
commit d87b433398
6 changed files with 116 additions and 82 deletions

View File

@@ -26,6 +26,9 @@ import fr.dcproject.component.auth.UserRepository
import fr.dcproject.component.auth.routes.authLogin
import fr.dcproject.component.auth.routes.authRegister
import fr.dcproject.component.auth.routes.authSso
import fr.dcproject.component.comment.article.routes.createCommentArticle
import fr.dcproject.component.comment.article.routes.getArticleComments
import fr.dcproject.component.comment.article.routes.getCitizenArticleComments
import fr.dcproject.event.EventNotification
import fr.dcproject.event.EventSubscriber
import fr.dcproject.routes.*
@@ -175,6 +178,10 @@ fun Application.module(env: Env = PROD) {
getOneComment(get(), get())
createCommentChildren(get(), get())
getChildrenComments(get(), get())
/* Comment Article */
getArticleComments(get(), get())
createCommentArticle(get(), get())
getCitizenArticleComments(get(), get())
/* Auth */
authLogin(get())
authRegister(get())
@@ -183,7 +190,6 @@ fun Application.module(env: Env = PROD) {
constitution(get())
followArticle(get())
followConstitution(get())
commentArticle(get(), get())
commentConstitution(get(), get())
voteArticle(get(), get(), get())
voteConstitution(get())

View File

@@ -48,7 +48,8 @@ class CommentArticleRepository(requester: Requester) : CommentRepositoryAbs<Arti
)
enum class Sort(val sql: String) {
CREATED_AT("created_at"), VOTES("votes");
CREATED_AT("created_at"),
VOTES("votes");
companion object {
fun fromString(string: String): Sort? {

View File

@@ -0,0 +1,44 @@
package fr.dcproject.component.comment.article.routes
import fr.dcproject.citizen
import fr.dcproject.citizenOrNull
import fr.dcproject.component.article.ArticleForView
import fr.dcproject.component.comment.article.CommentArticleRepository
import fr.dcproject.component.comment.generic.CommentForUpdate
import fr.dcproject.component.comment.generic.CommentVoter
import fr.dcproject.voter.assert
import io.ktor.application.*
import io.ktor.http.*
import io.ktor.locations.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
@KtorExperimentalLocationsAPI
@Location("/articles/{article}/comments")
class PostArticleCommentRequest(
val article: ArticleForView
) {
class Comment(
val content: String
)
suspend fun getComment(call: ApplicationCall) = call.receive<Comment>().run {
CommentForUpdate(
target = article,
createdBy = call.citizen,
content = content
)
}
}
@KtorExperimentalLocationsAPI
fun Route.createCommentArticle(repo: CommentArticleRepository, voter: CommentVoter) {
post<PostArticleCommentRequest> {
it.getComment(call).let { comment ->
voter.assert { canCreate(comment, citizenOrNull) }
repo.comment(comment)
call.respond(HttpStatusCode.Created, comment)
}
}
}

View File

@@ -0,0 +1,37 @@
package fr.dcproject.component.comment.article.routes
import fr.dcproject.citizenOrNull
import fr.dcproject.component.article.ArticleRef
import fr.dcproject.component.comment.article.CommentArticleRepository
import fr.dcproject.component.comment.generic.CommentVoter
import fr.dcproject.voter.assert
import io.ktor.application.*
import io.ktor.http.*
import io.ktor.locations.*
import io.ktor.response.*
import io.ktor.routing.*
@KtorExperimentalLocationsAPI
@Location("/articles/{article}/comments")
class ArticleCommentsRequest(
val article: ArticleRef,
page: Int = 1,
limit: Int = 50,
val search: String? = null,
sort: String = CommentArticleRepository.Sort.CREATED_AT.sql
) {
val page: Int = if (page < 1) 1 else page
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
val sort: CommentArticleRepository.Sort = CommentArticleRepository.Sort.fromString(sort) ?: CommentArticleRepository.Sort.CREATED_AT
}
@KtorExperimentalLocationsAPI
fun Route.getArticleComments(repo: CommentArticleRepository, voter: CommentVoter) {
get<ArticleCommentsRequest> {
val comment = repo.findByTarget(it.article, it.page, it.limit, it.sort)
if (comment.result.isNotEmpty()) {
voter.assert { canView(comment.result, citizenOrNull) }
}
call.respond(HttpStatusCode.OK, comment)
}
}

View File

@@ -0,0 +1,26 @@
package fr.dcproject.component.comment.article.routes
import fr.dcproject.citizenOrNull
import fr.dcproject.component.citizen.Citizen
import fr.dcproject.component.comment.article.CommentArticleRepository
import fr.dcproject.component.comment.generic.CommentVoter
import fr.dcproject.voter.assert
import io.ktor.application.*
import io.ktor.locations.*
import io.ktor.response.*
import io.ktor.routing.*
@KtorExperimentalLocationsAPI
@Location("/citizens/{citizen}/comments/articles")
class CitizenCommentArticleRequest(val citizen: Citizen)
@KtorExperimentalLocationsAPI
fun Route.getCitizenArticleComments(repo: CommentArticleRepository, voter: CommentVoter) {
get<CitizenCommentArticleRequest> {
repo.findByCitizen(it.citizen).let { comments ->
voter.assert { canView(comments.result, citizenOrNull) }
call.respond(comments)
}
}
}

View File

@@ -1,80 +0,0 @@
package fr.dcproject.routes
import fr.dcproject.citizen
import fr.dcproject.citizenOrNull
import fr.dcproject.component.article.ArticleForView
import fr.dcproject.component.article.ArticleRef
import fr.dcproject.component.citizen.Citizen
import fr.dcproject.component.comment.article.CommentArticleRepository
import fr.dcproject.component.comment.article.CommentArticleRepository.Sort
import fr.dcproject.component.comment.generic.CommentForUpdate
import fr.dcproject.component.comment.generic.CommentVoter
import fr.dcproject.voter.assert
import io.ktor.application.*
import io.ktor.http.*
import io.ktor.locations.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
@KtorExperimentalLocationsAPI
object CommentArticlePaths {
@Location("/articles/{article}/comments")
class ArticleCommentRequest(
val article: ArticleRef,
page: Int = 1,
limit: Int = 50,
val search: String? = null,
sort: String = Sort.CREATED_AT.sql
) {
val page: Int = if (page < 1) 1 else page
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
val sort: Sort = Sort.fromString(sort) ?: Sort.CREATED_AT
}
@Location("/articles/{article}/comments")
class PostArticleCommentRequest(
val article: ArticleForView
) {
class Comment(
val content: String
)
suspend fun getComment(call: ApplicationCall) = call.receive<Comment>().run {
CommentForUpdate(
target = article,
createdBy = call.citizen,
content = content
)
}
}
@Location("/citizens/{citizen}/comments/articles")
class CitizenCommentArticleRequest(val citizen: Citizen)
}
@KtorExperimentalLocationsAPI
fun Route.commentArticle(repo: CommentArticleRepository, voter: CommentVoter) {
get<CommentArticlePaths.ArticleCommentRequest> {
val comment = repo.findByTarget(it.article, it.page, it.limit, it.sort)
if (comment.result.isNotEmpty()) {
voter.assert { canView(comment.result, citizenOrNull) }
}
call.respond(HttpStatusCode.OK, comment)
}
post<CommentArticlePaths.PostArticleCommentRequest> {
it.getComment(call).let { comment ->
voter.assert { canCreate(comment, citizenOrNull) }
repo.comment(comment)
call.respond(HttpStatusCode.Created, comment)
}
}
get<CommentArticlePaths.CitizenCommentArticleRequest> {
repo.findByCitizen(it.citizen).let { comments ->
voter.assert { canView(comments.result, citizenOrNull) }
call.respond(comments)
}
}
}