diff --git a/src/main/kotlin/application/Application.kt b/src/main/kotlin/application/Application.kt index 15348a0..f68cfe5 100644 --- a/src/main/kotlin/application/Application.kt +++ b/src/main/kotlin/application/Application.kt @@ -29,6 +29,14 @@ import fr.dcproject.component.comment.generic.routes.createCommentChildren import fr.dcproject.component.comment.generic.routes.editComment import fr.dcproject.component.comment.generic.routes.getChildrenComments import fr.dcproject.component.comment.generic.routes.getOneComment +import fr.dcproject.component.follow.routes.article.FollowArticle.followArticle +import fr.dcproject.component.follow.routes.article.GetFollowArticle.getFollowArticle +import fr.dcproject.component.follow.routes.article.GetMyFollowsArticle.getMyFollowsArticle +import fr.dcproject.component.follow.routes.article.UnfollowArticle.unfollowArticle +import fr.dcproject.component.follow.routes.constitution.FollowConstitution.followConstitution +import fr.dcproject.component.follow.routes.constitution.GetFollowConstitution.getFollowConstitution +import fr.dcproject.component.follow.routes.constitution.GetMyFollowsConstitution.getMyFollowsConstitution +import fr.dcproject.component.follow.routes.constitution.UnfollowConstitution.unfollowConstitution import fr.dcproject.component.views.ConfigViews import fr.dcproject.component.workgroup.routes.CreateWorkgroup.createWorkgroup import fr.dcproject.component.workgroup.routes.DeleteWorkgroup.deleteWorkgroup @@ -43,8 +51,6 @@ import fr.dcproject.event.EventSubscriber import fr.dcproject.routes.commentConstitution import fr.dcproject.routes.constitution import fr.dcproject.routes.definition -import fr.dcproject.routes.followArticle -import fr.dcproject.routes.followConstitution import fr.dcproject.routes.notificationArticle import fr.dcproject.routes.opinionArticle import fr.dcproject.routes.opinionChoice @@ -186,10 +192,18 @@ fun Application.module(env: Env = PROD) { addMemberToWorkgroup(get(), get()) deleteMemberOfWorkgroup(get(), get()) updateMemberOfWorkgroup(get(), get()) - /* TODO */ - constitution(get(), get()) + /* Follows */ followArticle(get(), get()) followConstitution(get(), get()) + unfollowArticle(get(), get()) + unfollowConstitution(get(), get()) + getFollowArticle(get(), get()) + getFollowConstitution(get(), get()) + getMyFollowsArticle(get(), get()) + getMyFollowsConstitution(get(), get()) + + /* TODO */ + constitution(get(), get()) commentConstitution(get(), get()) voteArticle(get(), get(), get(), get()) voteConstitution(get(), get()) diff --git a/src/main/kotlin/application/KoinModule.kt b/src/main/kotlin/application/KoinModule.kt index f4942ca..a3007a7 100644 --- a/src/main/kotlin/application/KoinModule.kt +++ b/src/main/kotlin/application/KoinModule.kt @@ -17,6 +17,7 @@ import fr.dcproject.component.citizen.CitizenRepository import fr.dcproject.component.citizen.CitizenVoter import fr.dcproject.component.comment.article.CommentArticleRepository import fr.dcproject.component.comment.generic.CommentVoter +import fr.dcproject.component.follow.FollowVoter import fr.dcproject.component.workgroup.WorkgroupRepository import fr.dcproject.component.workgroup.WorkgroupVoter import fr.dcproject.event.publisher.Publisher @@ -24,7 +25,6 @@ import fr.dcproject.messages.Mailer import fr.dcproject.messages.NotificationEmailSender import fr.dcproject.repository.CommentConstitutionRepository import fr.dcproject.security.voter.ConstitutionVoter -import fr.dcproject.security.voter.FollowVoter import fr.dcproject.security.voter.OpinionChoiceVoter import fr.dcproject.security.voter.OpinionVoter import fr.dcproject.security.voter.VoteVoter @@ -41,9 +41,9 @@ import org.elasticsearch.client.RestClient import org.koin.core.qualifier.named import org.koin.dsl.module import fr.dcproject.component.comment.generic.CommentRepository as CommentGenericRepository +import fr.dcproject.component.follow.FollowArticleRepository as FollowArticleRepository +import fr.dcproject.component.follow.FollowConstitutionRepository as FollowConstitutionRepository import fr.dcproject.repository.Constitution as ConstitutionRepository -import fr.dcproject.repository.FollowArticle as FollowArticleRepository -import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository import fr.dcproject.repository.OpinionArticle as OpinionArticleRepository import fr.dcproject.repository.OpinionChoice as OpinionChoiceRepository import fr.dcproject.repository.VoteArticle as VoteArticleRepository diff --git a/src/main/kotlin/entity/Follow.kt b/src/main/kotlin/component/follow/Follow.kt similarity index 89% rename from src/main/kotlin/entity/Follow.kt rename to src/main/kotlin/component/follow/Follow.kt index 997c53b..7ac4ca3 100644 --- a/src/main/kotlin/entity/Follow.kt +++ b/src/main/kotlin/component/follow/Follow.kt @@ -1,8 +1,11 @@ -package fr.dcproject.entity +package fr.dcproject.component.follow import fr.dcproject.component.citizen.CitizenBasic import fr.dcproject.component.citizen.CitizenBasicI import fr.dcproject.component.citizen.CitizenI +import fr.dcproject.entity.ExtraI +import fr.dcproject.entity.HasTarget +import fr.dcproject.entity.TargetI import fr.postgresjson.entity.EntityCreatedAt import fr.postgresjson.entity.EntityCreatedAtImp import fr.postgresjson.entity.EntityCreatedBy diff --git a/src/main/kotlin/repository/Follow.kt b/src/main/kotlin/component/follow/FollowRepository.kt similarity index 89% rename from src/main/kotlin/repository/Follow.kt rename to src/main/kotlin/component/follow/FollowRepository.kt index 7de1a74..a26e69d 100644 --- a/src/main/kotlin/repository/Follow.kt +++ b/src/main/kotlin/component/follow/FollowRepository.kt @@ -1,12 +1,10 @@ -package fr.dcproject.repository +package fr.dcproject.component.follow import fr.dcproject.component.article.ArticleForView import fr.dcproject.component.article.ArticleRef import fr.dcproject.component.citizen.CitizenI import fr.dcproject.component.citizen.CitizenRef import fr.dcproject.entity.ConstitutionRef -import fr.dcproject.entity.FollowForUpdate -import fr.dcproject.entity.FollowSimple import fr.dcproject.entity.TargetRef import fr.postgresjson.connexion.Paginated import fr.postgresjson.connexion.Requester @@ -15,10 +13,10 @@ import fr.postgresjson.repository.RepositoryI import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import java.util.UUID +import fr.dcproject.component.follow.Follow as FollowEntity import fr.dcproject.entity.Constitution as ConstitutionEntity -import fr.dcproject.entity.Follow as FollowEntity -sealed class Follow(override var requester: Requester) : RepositoryI { +sealed class FollowRepository(override var requester: Requester) : RepositoryI { open fun findByCitizen( citizen: CitizenI, page: Int = 1, @@ -93,7 +91,7 @@ sealed class Follow(override var requester: Req ): Paginated> } -class FollowArticle(requester: Requester) : Follow(requester) { +class FollowArticleRepository(requester: Requester) : FollowRepository(requester) { override fun findByCitizen( citizenId: UUID, page: Int, @@ -124,7 +122,7 @@ class FollowArticle(requester: Requester) : Follow(r } } -class FollowConstitution(requester: Requester) : Follow(requester) { +class FollowConstitutionRepository(requester: Requester) : FollowRepository(requester) { override fun findByCitizen( citizenId: UUID, page: Int, diff --git a/src/main/kotlin/voter/FollowVoter.kt b/src/main/kotlin/component/follow/FollowVoter.kt similarity index 89% rename from src/main/kotlin/voter/FollowVoter.kt rename to src/main/kotlin/component/follow/FollowVoter.kt index e6598e0..f0f512f 100644 --- a/src/main/kotlin/voter/FollowVoter.kt +++ b/src/main/kotlin/component/follow/FollowVoter.kt @@ -1,10 +1,9 @@ -package fr.dcproject.security.voter +package fr.dcproject.component.follow import fr.dcproject.component.citizen.CitizenI -import fr.dcproject.entity.FollowI import fr.dcproject.voter.Voter import fr.dcproject.voter.VoterResponse -import fr.dcproject.entity.Follow as FollowEntity +import fr.dcproject.component.follow.Follow as FollowEntity class FollowVoter : Voter() { fun canCreate(subject: FollowI, citizen: CitizenI?): VoterResponse { diff --git a/src/main/kotlin/component/follow/routes/article/FollowArticle.kt b/src/main/kotlin/component/follow/routes/article/FollowArticle.kt new file mode 100644 index 0000000..159942a --- /dev/null +++ b/src/main/kotlin/component/follow/routes/article/FollowArticle.kt @@ -0,0 +1,31 @@ +package fr.dcproject.component.follow.routes.article + +import fr.dcproject.component.article.ArticleRef +import fr.dcproject.component.auth.citizen +import fr.dcproject.component.auth.citizenOrNull +import fr.dcproject.component.follow.FollowArticleRepository +import fr.dcproject.component.follow.FollowForUpdate +import fr.dcproject.component.follow.FollowVoter +import fr.dcproject.voter.assert +import io.ktor.application.call +import io.ktor.http.HttpStatusCode +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Location +import io.ktor.locations.post +import io.ktor.response.respond +import io.ktor.routing.Route + +@KtorExperimentalLocationsAPI +object FollowArticle { + @Location("/articles/{article}/follows") + class ArticleFollowRequest(val article: ArticleRef) + + fun Route.followArticle(repo: FollowArticleRepository, voter: FollowVoter) { + post { + val follow = FollowForUpdate(target = it.article, createdBy = this.citizen) + voter.assert { canCreate(follow, citizenOrNull) } + repo.follow(follow) + call.respond(HttpStatusCode.Created) + } + } +} diff --git a/src/main/kotlin/component/follow/routes/article/GetFollowArticle.kt b/src/main/kotlin/component/follow/routes/article/GetFollowArticle.kt new file mode 100644 index 0000000..dc64741 --- /dev/null +++ b/src/main/kotlin/component/follow/routes/article/GetFollowArticle.kt @@ -0,0 +1,30 @@ +package fr.dcproject.component.follow.routes.article + +import fr.dcproject.component.article.ArticleRef +import fr.dcproject.component.auth.citizen +import fr.dcproject.component.auth.citizenOrNull +import fr.dcproject.component.follow.FollowArticleRepository +import fr.dcproject.component.follow.FollowVoter +import fr.dcproject.voter.assert +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 +import io.ktor.response.respond +import io.ktor.routing.Route + +@KtorExperimentalLocationsAPI +object GetFollowArticle { + @Location("/articles/{article}/follows") + class ArticleFollowRequest(val article: ArticleRef) + + fun Route.getFollowArticle(repo: FollowArticleRepository, voter: FollowVoter) { + get { + repo.findFollow(citizen, it.article)?.let { follow -> + voter.assert { canView(follow, citizenOrNull) } + call.respond(follow) + } ?: call.respond(HttpStatusCode.NoContent) + } + } +} diff --git a/src/main/kotlin/component/follow/routes/article/GetMyFollowsArticle.kt b/src/main/kotlin/component/follow/routes/article/GetMyFollowsArticle.kt new file mode 100644 index 0000000..d8ae528 --- /dev/null +++ b/src/main/kotlin/component/follow/routes/article/GetMyFollowsArticle.kt @@ -0,0 +1,27 @@ +package fr.dcproject.component.follow.routes.article + +import fr.dcproject.component.auth.citizenOrNull +import fr.dcproject.component.citizen.Citizen +import fr.dcproject.component.follow.FollowArticleRepository +import fr.dcproject.component.follow.FollowVoter +import fr.dcproject.voter.assert +import io.ktor.application.call +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Location +import io.ktor.locations.get +import io.ktor.response.respond +import io.ktor.routing.Route + +@KtorExperimentalLocationsAPI +object GetMyFollowsArticle { + @Location("/citizens/{citizen}/follows/articles") + class CitizenFollowArticleRequest(val citizen: Citizen) + + fun Route.getMyFollowsArticle(repo: FollowArticleRepository, voter: FollowVoter) { + get { + val follows = repo.findByCitizen(it.citizen) + voter.assert { canView(follows.result, citizenOrNull) } + call.respond(follows) + } + } +} diff --git a/src/main/kotlin/component/follow/routes/article/UnfollowArticle.kt b/src/main/kotlin/component/follow/routes/article/UnfollowArticle.kt new file mode 100644 index 0000000..943c48a --- /dev/null +++ b/src/main/kotlin/component/follow/routes/article/UnfollowArticle.kt @@ -0,0 +1,31 @@ +package fr.dcproject.component.follow.routes.article + +import fr.dcproject.component.article.ArticleRef +import fr.dcproject.component.auth.citizen +import fr.dcproject.component.auth.citizenOrNull +import fr.dcproject.component.follow.FollowArticleRepository +import fr.dcproject.component.follow.FollowForUpdate +import fr.dcproject.component.follow.FollowVoter +import fr.dcproject.voter.assert +import io.ktor.application.call +import io.ktor.http.HttpStatusCode +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Location +import io.ktor.locations.delete +import io.ktor.response.respond +import io.ktor.routing.Route + +@KtorExperimentalLocationsAPI +object UnfollowArticle { + @Location("/articles/{article}/follows") + class ArticleFollowRequest(val article: ArticleRef) + + fun Route.unfollowArticle(repo: FollowArticleRepository, voter: FollowVoter) { + delete { + val follow = FollowForUpdate(target = it.article, createdBy = this.citizen) + voter.assert { canDelete(follow, citizenOrNull) } + repo.unfollow(follow) + call.respond(HttpStatusCode.NoContent) + } + } +} diff --git a/src/main/kotlin/component/follow/routes/constitution/FollowConstitution.kt b/src/main/kotlin/component/follow/routes/constitution/FollowConstitution.kt new file mode 100644 index 0000000..1130c85 --- /dev/null +++ b/src/main/kotlin/component/follow/routes/constitution/FollowConstitution.kt @@ -0,0 +1,31 @@ +package fr.dcproject.component.follow.routes.constitution + +import fr.dcproject.component.auth.citizen +import fr.dcproject.component.auth.citizenOrNull +import fr.dcproject.component.follow.FollowConstitutionRepository +import fr.dcproject.component.follow.FollowForUpdate +import fr.dcproject.component.follow.FollowVoter +import fr.dcproject.entity.ConstitutionRef +import fr.dcproject.voter.assert +import io.ktor.application.call +import io.ktor.http.HttpStatusCode +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Location +import io.ktor.locations.post +import io.ktor.response.respond +import io.ktor.routing.Route + +@KtorExperimentalLocationsAPI +object FollowConstitution { + @Location("/constitutions/{constitution}/follows") + class ConstitutionFollowRequest(val constitution: ConstitutionRef) + + fun Route.followConstitution(repo: FollowConstitutionRepository, voter: FollowVoter) { + post { + val follow = FollowForUpdate(target = it.constitution, createdBy = this.citizen) + voter.assert { canCreate(follow, citizenOrNull) } + repo.follow(follow) + call.respond(HttpStatusCode.Created) + } + } +} diff --git a/src/main/kotlin/component/follow/routes/constitution/GetFollowConstitution.kt b/src/main/kotlin/component/follow/routes/constitution/GetFollowConstitution.kt new file mode 100644 index 0000000..9988adc --- /dev/null +++ b/src/main/kotlin/component/follow/routes/constitution/GetFollowConstitution.kt @@ -0,0 +1,30 @@ +package fr.dcproject.component.follow.routes.constitution + +import fr.dcproject.component.auth.citizen +import fr.dcproject.component.auth.citizenOrNull +import fr.dcproject.component.follow.FollowConstitutionRepository +import fr.dcproject.component.follow.FollowVoter +import fr.dcproject.entity.ConstitutionRef +import fr.dcproject.voter.assert +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 +import io.ktor.response.respond +import io.ktor.routing.Route + +@KtorExperimentalLocationsAPI +object GetFollowConstitution { + @Location("/constitutions/{constitution}/follows") + class ConstitutionFollowRequest(val constitution: ConstitutionRef) + + fun Route.getFollowConstitution(repo: FollowConstitutionRepository, voter: FollowVoter) { + get { + repo.findFollow(citizen, it.constitution)?.let { follow -> + voter.assert { canView(follow, citizenOrNull) } + call.respond(follow) + } ?: call.respond(HttpStatusCode.NotFound) + } + } +} diff --git a/src/main/kotlin/component/follow/routes/constitution/GetMyFollowsConstitution.kt b/src/main/kotlin/component/follow/routes/constitution/GetMyFollowsConstitution.kt new file mode 100644 index 0000000..4cd78c2 --- /dev/null +++ b/src/main/kotlin/component/follow/routes/constitution/GetMyFollowsConstitution.kt @@ -0,0 +1,27 @@ +package fr.dcproject.component.follow.routes.constitution + +import fr.dcproject.component.auth.citizenOrNull +import fr.dcproject.component.citizen.CitizenRef +import fr.dcproject.component.follow.FollowConstitutionRepository +import fr.dcproject.component.follow.FollowVoter +import fr.dcproject.voter.assert +import io.ktor.application.call +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Location +import io.ktor.locations.get +import io.ktor.response.respond +import io.ktor.routing.Route + +@KtorExperimentalLocationsAPI +object GetMyFollowsConstitution { + @Location("/citizens/{citizen}/follows/constitutions") + class CitizenFollowConstitutionRequest(val citizen: CitizenRef) + + fun Route.getMyFollowsConstitution(repo: FollowConstitutionRepository, voter: FollowVoter) { + get { + val follows = repo.findByCitizen(it.citizen) + voter.assert { canView(follows.result, citizenOrNull) } + call.respond(follows) + } + } +} diff --git a/src/main/kotlin/component/follow/routes/constitution/UnfollowConstitution.kt b/src/main/kotlin/component/follow/routes/constitution/UnfollowConstitution.kt new file mode 100644 index 0000000..9f80002 --- /dev/null +++ b/src/main/kotlin/component/follow/routes/constitution/UnfollowConstitution.kt @@ -0,0 +1,31 @@ +package fr.dcproject.component.follow.routes.constitution + +import fr.dcproject.component.auth.citizen +import fr.dcproject.component.auth.citizenOrNull +import fr.dcproject.component.follow.FollowConstitutionRepository +import fr.dcproject.component.follow.FollowForUpdate +import fr.dcproject.component.follow.FollowVoter +import fr.dcproject.entity.ConstitutionRef +import fr.dcproject.voter.assert +import io.ktor.application.call +import io.ktor.http.HttpStatusCode +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Location +import io.ktor.locations.delete +import io.ktor.response.respond +import io.ktor.routing.Route + +@KtorExperimentalLocationsAPI +object UnfollowConstitution { + @Location("/constitutions/{constitution}/follows") + class ConstitutionUnfollowRequest(val constitution: ConstitutionRef) + + fun Route.unfollowConstitution(repo: FollowConstitutionRepository, voter: FollowVoter) { + delete { + val follow = FollowForUpdate(target = it.constitution, createdBy = this.citizen) + voter.assert { canDelete(follow, citizenOrNull) } + repo.unfollow(follow) + call.respond(HttpStatusCode.NoContent) + } + } +} diff --git a/src/main/kotlin/event/EventNotification.kt b/src/main/kotlin/event/EventNotification.kt index 1832dc0..5993854 100644 --- a/src/main/kotlin/event/EventNotification.kt +++ b/src/main/kotlin/event/EventNotification.kt @@ -9,11 +9,11 @@ import com.rabbitmq.client.Envelope import fr.dcproject.application.Configuration import fr.dcproject.component.article.ArticleForView import fr.dcproject.component.citizen.CitizenRef -import fr.dcproject.entity.FollowSimple +import fr.dcproject.component.follow.FollowRepository +import fr.dcproject.component.follow.FollowSimple import fr.dcproject.entity.TargetRef import fr.dcproject.event.publisher.Publisher import fr.dcproject.messages.NotificationEmailSender -import fr.dcproject.repository.Follow import fr.postgresjson.serializer.deserialize import io.ktor.application.ApplicationCall import io.ktor.application.EventDefinition @@ -27,7 +27,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.slf4j.Logger import org.slf4j.LoggerFactory -import fr.dcproject.repository.FollowArticle as FollowArticleRepository +import fr.dcproject.component.follow.FollowArticleRepository as FollowArticleRepository class ArticleUpdate( target: ArticleForView @@ -120,7 +120,7 @@ class EventNotification( val repo = when (event.type) { "article" -> followRepo else -> error("event '${event.type}' not implemented") - } as Follow<*, *> + } as FollowRepository<*, *> repo .findFollowsByTarget(event.target) diff --git a/src/main/kotlin/messages/NotificationEmailSender.kt b/src/main/kotlin/messages/NotificationEmailSender.kt index 5621c1a..2b23d04 100644 --- a/src/main/kotlin/messages/NotificationEmailSender.kt +++ b/src/main/kotlin/messages/NotificationEmailSender.kt @@ -8,7 +8,7 @@ import fr.dcproject.component.article.ArticleWithTitleI import fr.dcproject.component.citizen.CitizenBasicI import fr.dcproject.component.citizen.CitizenRef import fr.dcproject.component.citizen.CitizenRepository -import fr.dcproject.entity.FollowSimple +import fr.dcproject.component.follow.FollowSimple import fr.dcproject.entity.TargetRef import fr.postgresjson.entity.UuidEntityI import java.util.UUID diff --git a/src/main/kotlin/routes/FollowArticle.kt b/src/main/kotlin/routes/FollowArticle.kt deleted file mode 100644 index 95dc982..0000000 --- a/src/main/kotlin/routes/FollowArticle.kt +++ /dev/null @@ -1,60 +0,0 @@ -package fr.dcproject.routes - -import fr.dcproject.component.article.ArticleRef -import fr.dcproject.component.auth.citizen -import fr.dcproject.component.auth.citizenOrNull -import fr.dcproject.component.citizen.Citizen -import fr.dcproject.entity.FollowForUpdate -import fr.dcproject.security.voter.FollowVoter -import fr.dcproject.voter.assert -import io.ktor.application.call -import io.ktor.http.HttpStatusCode -import io.ktor.locations.KtorExperimentalLocationsAPI -import io.ktor.locations.Location -import io.ktor.locations.delete -import io.ktor.locations.get -import io.ktor.locations.post -import io.ktor.response.respond -import io.ktor.routing.Route -import fr.dcproject.repository.FollowArticle as FollowArticleRepository - -@KtorExperimentalLocationsAPI -object FollowArticlePaths { - @Location("/articles/{article}/follows") - class ArticleFollowRequest(val article: ArticleRef) - - @Location("/citizens/{citizen}/follows/articles") - class CitizenFollowArticleRequest(val citizen: Citizen) -} - -@KtorExperimentalLocationsAPI -fun Route.followArticle(repo: FollowArticleRepository, voter: FollowVoter) { - post { - val follow = FollowForUpdate(target = it.article, createdBy = this.citizen) - voter.assert { canCreate(follow, citizenOrNull) } - repo.follow(follow) - call.respond(HttpStatusCode.Created) - } - - delete { - val follow = FollowForUpdate(target = it.article, createdBy = this.citizen) - voter.assert { canDelete(follow, citizenOrNull) } - repo.unfollow(follow) - call.respond(HttpStatusCode.NoContent) - } - - get { - repo.findFollow(citizen, it.article)?.let { follow -> - voter.assert { canView(follow, citizenOrNull) } - call.respond(follow) - } ?: call.respond(HttpStatusCode.NoContent) - } - - get { - val follows = repo.findByCitizen(it.citizen) - if (follows.result.isNotEmpty()) { - voter.assert { canView(follows.result, citizenOrNull) } - } - call.respond(follows) - } -} diff --git a/src/main/kotlin/routes/FollowConstitution.kt b/src/main/kotlin/routes/FollowConstitution.kt deleted file mode 100644 index a6b39d8..0000000 --- a/src/main/kotlin/routes/FollowConstitution.kt +++ /dev/null @@ -1,58 +0,0 @@ -package fr.dcproject.routes - -import fr.dcproject.component.auth.citizen -import fr.dcproject.component.auth.citizenOrNull -import fr.dcproject.component.citizen.CitizenRef -import fr.dcproject.entity.ConstitutionRef -import fr.dcproject.entity.FollowForUpdate -import fr.dcproject.security.voter.FollowVoter -import fr.dcproject.voter.assert -import io.ktor.application.call -import io.ktor.http.HttpStatusCode -import io.ktor.locations.KtorExperimentalLocationsAPI -import io.ktor.locations.Location -import io.ktor.locations.delete -import io.ktor.locations.get -import io.ktor.locations.post -import io.ktor.response.respond -import io.ktor.routing.Route -import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository - -@KtorExperimentalLocationsAPI -object FollowConstitutionPaths { - @Location("/constitutions/{constitution}/follows") - class ConstitutionFollowRequest(val constitution: ConstitutionRef) - - @Location("/citizens/{citizen}/follows/constitutions") - class CitizenFollowConstitutionRequest(val citizen: CitizenRef) -} - -@KtorExperimentalLocationsAPI -fun Route.followConstitution(repo: FollowConstitutionRepository, voter: FollowVoter) { - post { - val follow = FollowForUpdate(target = it.constitution, createdBy = this.citizen) - voter.assert { canCreate(follow, citizenOrNull) } - repo.follow(follow) - call.respond(HttpStatusCode.Created) - } - - delete { - val follow = FollowForUpdate(target = it.constitution, createdBy = this.citizen) - voter.assert { canDelete(follow, citizenOrNull) } - repo.unfollow(follow) - call.respond(HttpStatusCode.NoContent) - } - - get { - repo.findFollow(citizen, it.constitution)?.let { follow -> - voter.assert { canView(follow, citizenOrNull) } - call.respond(follow) - } ?: call.respond(HttpStatusCode.NotFound) - } - - get { - val follows = repo.findByCitizen(it.citizen) - voter.assert { canView(follows.result, citizenOrNull) } - call.respond(follows) - } -} diff --git a/src/test/kotlin/steps/FollowSteps.kt b/src/test/kotlin/steps/FollowSteps.kt index bc63736..1e0b38e 100644 --- a/src/test/kotlin/steps/FollowSteps.kt +++ b/src/test/kotlin/steps/FollowSteps.kt @@ -2,14 +2,14 @@ package steps import fr.dcproject.component.article.ArticleRef import fr.dcproject.component.citizen.CitizenRepository +import fr.dcproject.component.follow.FollowForUpdate import fr.dcproject.entity.ConstitutionRef -import fr.dcproject.entity.FollowForUpdate import fr.dcproject.utils.toUUID import io.cucumber.java8.En import org.koin.test.KoinTest import org.koin.test.get -import fr.dcproject.repository.FollowArticle as FollowArticleRepository -import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository +import fr.dcproject.component.follow.FollowArticleRepository as FollowArticleRepository +import fr.dcproject.component.follow.FollowConstitutionRepository as FollowConstitutionRepository class FollowSteps : En, KoinTest { init { diff --git a/src/test/kotlin/unit/voter/CommentVoterTest.kt b/src/test/kotlin/unit/voter/CommentVoterTest.kt index bca6f1d..2d609d8 100644 --- a/src/test/kotlin/unit/voter/CommentVoterTest.kt +++ b/src/test/kotlin/unit/voter/CommentVoterTest.kt @@ -12,9 +12,6 @@ import fr.dcproject.component.comment.generic.CommentForView import fr.dcproject.component.comment.generic.CommentVoter import fr.dcproject.voter.Vote.DENIED import fr.dcproject.voter.Vote.GRANTED -import fr.postgresjson.connexion.Paginated -import io.mockk.every -import io.mockk.mockk import org.amshove.kluent.`should be` import org.joda.time.DateTime import org.junit.jupiter.api.Tag @@ -23,7 +20,6 @@ import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.parallel.Execution import org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT import java.util.UUID -import fr.dcproject.component.article.ArticleRepository as ArticleRepo @TestInstance(TestInstance.Lifecycle.PER_CLASS) @Execution(CONCURRENT) @@ -101,10 +97,6 @@ internal class CommentVoterTest { target = ArticleRef() ) - private val repoArticle1 = mockk { - every { findVersionsByVersionId(1, 1, any()) } returns Paginated(listOf(article1), 0, 1, 1) - } - @Test fun `can be view the comment`() { CommentVoter() diff --git a/src/test/kotlin/unit/voter/FollowVoterTest.kt b/src/test/kotlin/unit/voter/FollowVoterTest.kt index 66ade49..d7c7113 100644 --- a/src/test/kotlin/unit/voter/FollowVoterTest.kt +++ b/src/test/kotlin/unit/voter/FollowVoterTest.kt @@ -7,11 +7,10 @@ import fr.dcproject.component.citizen.Citizen import fr.dcproject.component.citizen.CitizenBasic import fr.dcproject.component.citizen.CitizenCart import fr.dcproject.component.citizen.CitizenI -import fr.dcproject.entity.Follow -import fr.dcproject.security.voter.FollowVoter +import fr.dcproject.component.follow.Follow +import fr.dcproject.component.follow.FollowVoter import fr.dcproject.voter.Vote.DENIED import fr.dcproject.voter.Vote.GRANTED -import io.mockk.mockkStatic import org.amshove.kluent.`should be` import org.joda.time.DateTime import org.junit.jupiter.api.Tag @@ -96,10 +95,6 @@ internal class FollowVoterTest { target = article1 ) - init { - mockkStatic("fr.dcproject.component.auth.CitizenContextKt") - } - @Test fun `can be view the follow`() { FollowVoter() diff --git a/src/test/kotlin/unit/voter/OpinionChoiceVoterTest.kt b/src/test/kotlin/unit/voter/OpinionChoiceVoterTest.kt index 37fe255..50bce1c 100644 --- a/src/test/kotlin/unit/voter/OpinionChoiceVoterTest.kt +++ b/src/test/kotlin/unit/voter/OpinionChoiceVoterTest.kt @@ -9,7 +9,6 @@ import fr.dcproject.component.citizen.CitizenI import fr.dcproject.entity.OpinionChoice import fr.dcproject.security.voter.OpinionChoiceVoter import fr.dcproject.voter.Vote.GRANTED -import io.mockk.mockkStatic import org.amshove.kluent.`should be` import org.joda.time.DateTime import org.junit.jupiter.api.Tag @@ -56,10 +55,6 @@ internal class OpinionChoiceVoterTest { target = listOf() ) - init { - mockkStatic("fr.dcproject.component.auth.CitizenContextKt") - } - @Test fun `can be view the opinion choice`() { OpinionChoiceVoter() diff --git a/src/test/kotlin/unit/voter/OpinionVoterTest.kt b/src/test/kotlin/unit/voter/OpinionVoterTest.kt index 08f9451..055b6c2 100644 --- a/src/test/kotlin/unit/voter/OpinionVoterTest.kt +++ b/src/test/kotlin/unit/voter/OpinionVoterTest.kt @@ -11,7 +11,6 @@ import fr.dcproject.entity.OpinionChoice import fr.dcproject.security.voter.OpinionVoter import fr.dcproject.voter.Vote.DENIED import fr.dcproject.voter.Vote.GRANTED -import io.mockk.mockkStatic import org.amshove.kluent.`should be` import org.joda.time.DateTime import org.junit.jupiter.api.Tag @@ -73,10 +72,6 @@ internal class OpinionVoterTest { ) ) - init { - mockkStatic("fr.dcproject.component.auth.CitizenContextKt") - } - @Test fun `can be view the opinion`() { OpinionVoter() diff --git a/src/test/kotlin/unit/voter/VoteVoterTest.kt b/src/test/kotlin/unit/voter/VoteVoterTest.kt index b1cd605..e5f2b5d 100644 --- a/src/test/kotlin/unit/voter/VoteVoterTest.kt +++ b/src/test/kotlin/unit/voter/VoteVoterTest.kt @@ -1,7 +1,6 @@ package unit.voter import fr.dcproject.component.article.ArticleForView -import fr.dcproject.component.article.ArticleRef import fr.dcproject.component.auth.User import fr.dcproject.component.auth.UserI import fr.dcproject.component.citizen.Citizen @@ -12,7 +11,6 @@ import fr.dcproject.entity.VoteForUpdate import fr.dcproject.security.voter.VoteVoter import fr.dcproject.voter.Vote.DENIED import fr.dcproject.voter.Vote.GRANTED -import io.mockk.mockkStatic import org.amshove.kluent.`should be` import org.joda.time.DateTime import org.junit.jupiter.api.Tag @@ -101,16 +99,6 @@ internal class VoteVoterTest { note = 1 ) - private val voteWithoutTargetUser = VoteForUpdate( - createdBy = tesla, - target = ArticleRef(), - note = 1 - ) - - init { - mockkStatic("fr.dcproject.component.auth.CitizenContextKt") - } - @Test fun `can be view your the vote`() { VoteVoter()