Refactors Articles and Voter
- Move files into components (article) - Split articles routes - Refactoring for remove ktor-voter (ArticleVoter) - Remove mutability - Move DataConversion to separate file (Converter.kt) - Add Schemas for Articles routes - Fix SQL Query for Workgroup roles - rename container_name in docker-compose
This commit is contained in:
@@ -1,101 +0,0 @@
|
||||
import fr.dcproject.entity.Article
|
||||
import fr.dcproject.entity.CitizenBasic
|
||||
import fr.dcproject.entity.CitizenI
|
||||
import fr.dcproject.entity.User
|
||||
import fr.postgresjson.serializer.deserialize
|
||||
import fr.postgresjson.serializer.serialize
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import org.amshove.kluent.`should be equal to`
|
||||
import org.amshove.kluent.shouldBe
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@KtorExperimentalAPI
|
||||
@TestInstance(PER_CLASS)
|
||||
class ArticleTest {
|
||||
@Language("JSON")
|
||||
private val articleJson: String = """
|
||||
{
|
||||
"id": "83b0b60a-5ab3-44f2-b243-1dc469a7564f",
|
||||
"title": "Hello world!",
|
||||
"anonymous": true,
|
||||
"content": "bla bla bla",
|
||||
"description": "this is the changement !",
|
||||
"tags": [],
|
||||
"draft": false,
|
||||
"last_version": false,
|
||||
"created_by": {
|
||||
"id": "94a0d350-7eab-4a6e-9f84-0c2e7635b67c",
|
||||
"name": {
|
||||
"first_name": "Jaque",
|
||||
"last_name": "Bono",
|
||||
"civility": null
|
||||
},
|
||||
"email": "jaque.bono@gmail.com",
|
||||
"birthday": "2020-03-16T01:48:27.020Z",
|
||||
"vote_anonymous": true,
|
||||
"follow_anonymous": true,
|
||||
"user": {
|
||||
"id": "2bc356a2-4d3e-46ff-91f4-ae30fb7fa67d",
|
||||
"username": "jaque",
|
||||
"blocked_at": null,
|
||||
"plain_password": "azerty",
|
||||
"roles": [],
|
||||
"created_at": "2020-03-16T01:48:24.153Z",
|
||||
"updated_at": "2020-03-16T01:48:24.516Z"
|
||||
},
|
||||
"deleted_at": null,
|
||||
"deleted": false
|
||||
},
|
||||
"reference": "article",
|
||||
"views": {
|
||||
"total": 0,
|
||||
"unique": 0,
|
||||
"updated_at": "2020-03-16T01:48:31.070Z"
|
||||
},
|
||||
"version_id": "27cb4f5d-d425-4e10-95ca-6c50fac73408",
|
||||
"version_number": null,
|
||||
"created_at": "2020-03-16T01:48:31.004Z",
|
||||
"deleted_at": null,
|
||||
"deleted": false,
|
||||
"votes": {
|
||||
"up": 0,
|
||||
"neutral": 0,
|
||||
"down": 0,
|
||||
"total": 0,
|
||||
"score": 0,
|
||||
"updated_at": null
|
||||
},
|
||||
"opinions": {}
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
@Test
|
||||
fun `test Article serialize`() {
|
||||
val user = User(username = "jaque", plainPassword = "azerty")
|
||||
val citizen = CitizenBasic(
|
||||
name = CitizenI.Name("Jaque", "Bono"),
|
||||
birthday = DateTime.now(),
|
||||
email = "jaque.bono@gmail.com",
|
||||
user = user
|
||||
)
|
||||
val article = Article(
|
||||
title = "Hello world!",
|
||||
content = "bla bla bla",
|
||||
description = "this is the changement !",
|
||||
createdBy = citizen
|
||||
)
|
||||
article.serialize().contains("""Hello world!""") shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Article Deserialize`() {
|
||||
val article2: Article = articleJson.deserialize()!!
|
||||
article2.id.toString() `should be equal to` "83b0b60a-5ab3-44f2-b243-1dc469a7564f"
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
import fr.dcproject.entity.CitizenBasic
|
||||
import fr.dcproject.entity.CitizenI
|
||||
import fr.dcproject.entity.Constitution
|
||||
import fr.dcproject.entity.User
|
||||
import fr.postgresjson.serializer.deserialize
|
||||
import fr.postgresjson.serializer.serialize
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import org.amshove.kluent.`should be equal to`
|
||||
import org.amshove.kluent.`should equal`
|
||||
import org.amshove.kluent.shouldBe
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@KtorExperimentalAPI
|
||||
@TestInstance(PER_CLASS)
|
||||
class ConstitutionTest {
|
||||
@Language("JSON")
|
||||
private val constitutionJson: String = """{
|
||||
"id":"15814bb6-8d90-4c6a-a456-c3939a8ec75e",
|
||||
"title":"Hello world!",
|
||||
"anonymous":true,
|
||||
"titles":[
|
||||
{
|
||||
"id":"8156b66f-a9c8-4fd9-8375-a8a1f42ccfd2",
|
||||
"name":"plop",
|
||||
"rank":0,
|
||||
"created_by":{
|
||||
"id":"18902d22-245d-4d44-b23d-9f0e82688612",
|
||||
"name":{
|
||||
"first_name":"Jaque",
|
||||
"last_name":"Bono",
|
||||
"civility":null
|
||||
},
|
||||
"email": "jaque.bono@gmail.com",
|
||||
"birthday":"2019-08-07T20:34:08.013Z",
|
||||
"user_id":null,
|
||||
"vote_anonymous":null,
|
||||
"follow_anonymous":null,
|
||||
"user":{
|
||||
"id":"257abe9f-be17-4ad3-ae6a-b1dc9706d5d7",
|
||||
"username":"jaque",
|
||||
"blocked_at":null,
|
||||
"plain_password":"azerty",
|
||||
"created_at":null,
|
||||
"updated_at":null
|
||||
},
|
||||
"created_at":null
|
||||
},
|
||||
"created_at":null
|
||||
}
|
||||
],
|
||||
"created_by":{
|
||||
"id":"18902d22-245d-4d44-b23d-9f0e82688612",
|
||||
"name":{
|
||||
"first_name":"Jaque",
|
||||
"last_name":"Bono",
|
||||
"civility":null
|
||||
},
|
||||
"email": "jaque.bono@gmail.com",
|
||||
"birthday":"2019-08-07T20:34:08.013Z",
|
||||
"user_id":null,
|
||||
"vote_anonymous":null,
|
||||
"follow_anonymous":null,
|
||||
"user":{
|
||||
"id":"257abe9f-be17-4ad3-ae6a-b1dc9706d5d7",
|
||||
"username":"jaque",
|
||||
"plain_password":"azerty"
|
||||
}
|
||||
},
|
||||
"created_at":null,
|
||||
"version_id":"3311a7af-2a62-4e31-b4cd-889f8ead9737",
|
||||
"version_number":null
|
||||
}""".trimIndent()
|
||||
|
||||
@Test
|
||||
fun `test Constitution serialize`() {
|
||||
val user = User(username = "jaque", plainPassword = "azerty")
|
||||
val citizen = CitizenBasic(
|
||||
name = CitizenI.Name("Jaque", "Bono"),
|
||||
email = "jaque.bono@gmail.com",
|
||||
birthday = DateTime.now(),
|
||||
user = user
|
||||
)
|
||||
val title1 = Constitution.Title(
|
||||
name = "plop"
|
||||
)
|
||||
val constitution = Constitution(
|
||||
title = "Hello world!",
|
||||
anonymous = true,
|
||||
titles = mutableListOf(title1),
|
||||
createdBy = citizen
|
||||
)
|
||||
println(constitution.serialize())
|
||||
constitution.serialize().contains("""Hello world!""") shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Constitution Deserialize`() {
|
||||
val constitution2: Constitution = constitutionJson.deserialize()!!
|
||||
constitution2.id.toString() `should be equal to` "15814bb6-8d90-4c6a-a456-c3939a8ec75e"
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
import fr.dcproject.entity.*
|
||||
import fr.postgresjson.serializer.deserialize
|
||||
import fr.postgresjson.serializer.serialize
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import org.amshove.kluent.`should be equal to`
|
||||
import org.amshove.kluent.`should equal`
|
||||
import org.amshove.kluent.shouldBe
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@KtorExperimentalAPI
|
||||
@TestInstance(PER_CLASS)
|
||||
class FollowTest {
|
||||
@Language("JSON")
|
||||
private val followJson: String = """{
|
||||
"id":"bae81585-d985-4d7a-9b58-3a13e911688a",
|
||||
"created_by":{
|
||||
"id":"4a87ad24-187a-46a8-97ab-00b30a24e561",
|
||||
"name":{
|
||||
"first_name":"Jaque",
|
||||
"last_name":"Bono",
|
||||
"civility":null
|
||||
},
|
||||
"email": "jaque.bono@gmail.com",
|
||||
"birthday":"2019-08-09T11:42:47.168Z",
|
||||
"user_id":null,
|
||||
"vote_anonymous":null,
|
||||
"follow_anonymous":null,
|
||||
"user":{
|
||||
"id":"721db690-d050-46e6-92b0-056f2e8ba993",
|
||||
"username":"jaque",
|
||||
"blocked_at":null,
|
||||
"plain_password":"azerty",
|
||||
"created_at":"2019-08-09T11:42:47.168Z",
|
||||
"updated_at":"2019-08-09T11:42:47.168Z"
|
||||
},
|
||||
"created_at":"2019-08-09T11:42:47.168Z"
|
||||
},
|
||||
"target":{
|
||||
"id":"34588ea7-c180-4694-801b-1b5c5a6ed73f",
|
||||
"title":"Hello world!",
|
||||
"anonymous":true,
|
||||
"content":"bla bla bla",
|
||||
"description":"this is the changement !",
|
||||
"tags":[
|
||||
|
||||
],
|
||||
"created_by":{
|
||||
"id":"4a87ad24-187a-46a8-97ab-00b30a24e561",
|
||||
"name":{
|
||||
"first_name":"Jaque",
|
||||
"last_name":"Bono",
|
||||
"civility":null
|
||||
},
|
||||
"email": "jaque.bono@gmail.com",
|
||||
"birthday":"2019-08-09T11:42:47.168Z",
|
||||
"user_id":null,
|
||||
"vote_anonymous":null,
|
||||
"follow_anonymous":null,
|
||||
"user":{
|
||||
"id":"721db690-d050-46e6-92b0-056f2e8ba993",
|
||||
"username":"jaque",
|
||||
"blocked_at":null,
|
||||
"plain_password":"azerty",
|
||||
"created_at":"2019-08-09T11:42:47.168Z",
|
||||
"updated_at":"2019-08-09T11:42:47.168Z"
|
||||
}
|
||||
},
|
||||
"version_id":"a4aa7dd4-d174-42d2-9ba5-ae6f1129ffce",
|
||||
"version_number":null,
|
||||
"created_at":null
|
||||
},
|
||||
"created_at":"2019-08-09T11:42:47.168Z"
|
||||
}""".trimIndent()
|
||||
|
||||
@Test
|
||||
fun `test Follow Article serialize`() {
|
||||
val user = User(username = "jaque", plainPassword = "azerty")
|
||||
val citizen = CitizenBasic(
|
||||
name = CitizenI.Name("Jaque", "Bono"),
|
||||
email = "jaque.bono@gmail.com",
|
||||
birthday = DateTime.now(),
|
||||
user = user
|
||||
)
|
||||
val article = Article(
|
||||
title = "Hello world!",
|
||||
content = "bla bla bla",
|
||||
description = "this is the changement !",
|
||||
createdBy = citizen
|
||||
)
|
||||
val follow = Follow(
|
||||
createdBy = citizen,
|
||||
target = article
|
||||
)
|
||||
follow.serialize().contains("""Hello world!""") shouldBe true
|
||||
println(follow.serialize())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Follow Article Deserialize`() {
|
||||
val follow: Follow<ArticleSimple> = followJson.deserialize()!!
|
||||
follow.id.toString() `should be equal to` "bae81585-d985-4d7a-9b58-3a13e911688a"
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
import fr.dcproject.Env
|
||||
import fr.dcproject.entity.ArticleRefVersioning
|
||||
import fr.dcproject.component.article.ArticleRefVersioning
|
||||
import fr.dcproject.component.article.ArticleViewManager
|
||||
import fr.dcproject.entity.CitizenRef
|
||||
import fr.dcproject.module
|
||||
import fr.dcproject.views.ArticleViewManager
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.server.testing.withTestApplication
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import io.ktor.locations.*
|
||||
import io.ktor.server.testing.*
|
||||
import io.ktor.util.*
|
||||
import org.amshove.kluent.`should be equal to`
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
import fr.dcproject.entity.*
|
||||
import fr.postgresjson.serializer.deserialize
|
||||
import fr.postgresjson.serializer.serialize
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import org.amshove.kluent.`should be equal to`
|
||||
import org.amshove.kluent.`should equal`
|
||||
import org.amshove.kluent.shouldBe
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@KtorExperimentalAPI
|
||||
@TestInstance(PER_CLASS)
|
||||
class VoteTest {
|
||||
@Language("JSON")
|
||||
private val voteJson: String = """
|
||||
{
|
||||
"id": "032acc3d-e8c5-4cb2-9297-bec913ff8d9b",
|
||||
"created_by": {
|
||||
"id": "40c65a43-f9f8-45cd-aa31-953376e7c94a",
|
||||
"name": {
|
||||
"first_name": "Jaque",
|
||||
"last_name": "Bono",
|
||||
"civility": null
|
||||
},
|
||||
"email": "jaque.bono@gmail.com",
|
||||
"birthday": "2019-10-01T10:59:40.570Z",
|
||||
"user_id": null,
|
||||
"vote_anonymous": true,
|
||||
"follow_anonymous": true,
|
||||
"user": {
|
||||
"id": "f68df389-fb0d-423e-90fd-a140a9ed29b9",
|
||||
"username": "jaque",
|
||||
"blocked_at": null,
|
||||
"plain_password": "azerty",
|
||||
"roles": [],
|
||||
"created_at": "2019-10-01T10:59:40.570Z",
|
||||
"updated_at": "2019-10-01T10:59:40.570Z"
|
||||
},
|
||||
"deleted": false,
|
||||
"created_at": "2019-10-01T10:59:40.570Z",
|
||||
"updated_at": "2019-10-01T10:59:40.570Z",
|
||||
"deleted_at": null
|
||||
},
|
||||
"target": {
|
||||
"id": "90f28912-7bd5-4f37-a0ea-8620e3817d51",
|
||||
"title": "Hello world!",
|
||||
"anonymous": true,
|
||||
"content": "bla bla bla",
|
||||
"description": "this is the changement !",
|
||||
"tags": [],
|
||||
"draft": false,
|
||||
"last_version": false,
|
||||
"created_by": {
|
||||
"id": "40c65a43-f9f8-45cd-aa31-953376e7c94a",
|
||||
"name": {
|
||||
"first_name": "Jaque",
|
||||
"last_name": "Bono",
|
||||
"civility": null
|
||||
},
|
||||
"email": "jaque.bono@gmail.com",
|
||||
"birthday": "2019-10-01T10:59:40.570Z",
|
||||
"user_id": null,
|
||||
"vote_anonymous": true,
|
||||
"follow_anonymous": true,
|
||||
"user": {
|
||||
"id": "f68df389-fb0d-423e-90fd-a140a9ed29b9",
|
||||
"username": "jaque",
|
||||
"blocked_at": null,
|
||||
"plain_password": "azerty",
|
||||
"roles": [],
|
||||
"created_at": "2019-08-09T11:42:47.168Z",
|
||||
"updated_at": "2019-08-09T11:42:47.168Z"
|
||||
},
|
||||
"deleted": false,
|
||||
"created_at": "2019-08-09T11:42:47.168Z",
|
||||
"deleted_at": "2019-08-09T11:42:47.168Z"
|
||||
},
|
||||
"votes": {
|
||||
"up": 0,
|
||||
"neutral": 0,
|
||||
"down": 0,
|
||||
"updated_at": null
|
||||
},
|
||||
"version_id": "48dad61e-c54b-4f4c-9f66-428f90b94045",
|
||||
"version_number": null,
|
||||
"deleted": false,
|
||||
"created_at": "2019-10-01T10:59:40.570Z",
|
||||
"deleted_at": "2019-10-01T10:59:40.570Z"
|
||||
},
|
||||
"note": -1,
|
||||
"anonymous": true,
|
||||
"updated_at": "2019-10-01T10:59:40.570Z",
|
||||
"created_at": "2019-10-01T10:59:40.570Z"
|
||||
}""".trimIndent()
|
||||
|
||||
@Test
|
||||
fun `test Vote Article serialize`() {
|
||||
val user = User(username = "jaque", plainPassword = "azerty")
|
||||
val citizen = CitizenBasic(
|
||||
name = CitizenI.Name("Jaque", "Bono"),
|
||||
email = "jaque.bono@gmail.com",
|
||||
birthday = DateTime.now(),
|
||||
user = user
|
||||
)
|
||||
val article = Article(
|
||||
title = "Hello world!",
|
||||
content = "bla bla bla",
|
||||
description = "this is the changement !",
|
||||
createdBy = citizen
|
||||
)
|
||||
val vote = Vote(
|
||||
createdBy = citizen,
|
||||
target = article,
|
||||
note = -1
|
||||
)
|
||||
vote.serialize().contains("""Hello world!""") shouldBe true
|
||||
vote.serialize().contains("-1") shouldBe true
|
||||
println(vote.serialize())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Vote Article Deserialize`() {
|
||||
val vote: Vote<Article> = voteJson.deserialize()!!
|
||||
vote.id.toString() `should be equal to` "032acc3d-e8c5-4cb2-9297-bec913ff8d9b"
|
||||
vote.note.toString() `should be equal to` "-1"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package feature
|
||||
|
||||
import fr.dcproject.component.article.ArticleForUpdate
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.component.article.ArticleRepository
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.repository.CommentArticle
|
||||
import fr.dcproject.utils.toUUID
|
||||
@@ -9,10 +12,7 @@ import org.joda.time.DateTime
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.get
|
||||
import java.util.*
|
||||
import fr.dcproject.entity.Article as ArticleEntity
|
||||
import fr.dcproject.entity.Comment as CommentEntity
|
||||
import fr.dcproject.entity.User as UserEntity
|
||||
import fr.dcproject.repository.Article as ArticleRepository
|
||||
import fr.dcproject.repository.Citizen as CitizenRepository
|
||||
|
||||
class ArticleSteps : En, KoinTest {
|
||||
@@ -88,7 +88,7 @@ class ArticleSteps : En, KoinTest {
|
||||
("$firstName-$lastName".toLowerCase()).toLowerCase().replace(' ', '-')
|
||||
) ?: error("Citizen not exist")
|
||||
|
||||
val comment: CommentEntity<ArticleEntity> = CommentEntity(
|
||||
val comment: CommentForUpdate<ArticleForView, Citizen> = CommentForUpdate(
|
||||
id = id ?: params?.get("id")?.let { UUID.fromString(it) } ?: UUID.randomUUID(),
|
||||
createdBy = citizen,
|
||||
target = article,
|
||||
|
||||
@@ -26,13 +26,16 @@ class CitizenSteps : En, KoinTest {
|
||||
createCitizen(firstName, lastName)
|
||||
}
|
||||
|
||||
Given("I have citizen {word} {word} with") { firstName: String, lastName: String, extraData: DataTable? ->
|
||||
createCitizen(firstName, lastName, extraData)
|
||||
}
|
||||
|
||||
Given("I have citizen {word} {word} with ID {string}") { firstName: String, lastName: String, id: String ->
|
||||
createCitizen(firstName, lastName, id = UUID.fromString(id))
|
||||
}
|
||||
}
|
||||
|
||||
private fun createCitizen(firstName: String, lastName: String, extraData: DataTable? = null, id: UUID? = null) {
|
||||
|
||||
val params = extraData?.asMap<String, String>(String::class.java, String::class.java)
|
||||
val id: UUID = id ?: params?.get("id")?.let { UUID.fromString(it) } ?: UUID.randomUUID()
|
||||
val email = params?.get("email") ?: ("$firstName-$lastName".toLowerCase()) + "@dc-project.fr"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package feature
|
||||
|
||||
import fr.dcproject.component.article.ArticleRef
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.repository.CommentConstitution
|
||||
import fr.dcproject.utils.toUUID
|
||||
@@ -9,7 +10,6 @@ import org.joda.time.DateTime
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.get
|
||||
import java.util.*
|
||||
import fr.dcproject.entity.Comment as CommentEntity
|
||||
import fr.dcproject.entity.User as UserEntity
|
||||
import fr.dcproject.repository.Citizen as CitizenRepository
|
||||
import fr.dcproject.repository.Constitution as ConstitutionRepository
|
||||
@@ -66,7 +66,7 @@ class ConstitutionSteps : En, KoinTest {
|
||||
name = "My Title"
|
||||
)
|
||||
|
||||
val constitution = ConstitutionSimple<CitizenSimple, ConstitutionSimple.TitleSimple<ArticleRef>>(
|
||||
val constitution = ConstitutionSimple<CitizenWithUserI, ConstitutionSimple.TitleSimple<ArticleRef>>(
|
||||
id = id ?: params?.get("id")?.toUUID() ?: UUID.randomUUID(),
|
||||
title = "hello",
|
||||
titles = mutableListOf(title1),
|
||||
@@ -91,7 +91,7 @@ class ConstitutionSteps : En, KoinTest {
|
||||
("$firstName-$lastName".toLowerCase()).toLowerCase().replace(' ', '-')
|
||||
) ?: error("Citizen not exist")
|
||||
|
||||
val comment: CommentEntity<ConstitutionRef> = CommentEntity(
|
||||
val comment: CommentForUpdate<ConstitutionRef, Citizen> = CommentForUpdate(
|
||||
id = params?.get("id")?.let { UUID.fromString(it) } ?: UUID.randomUUID(),
|
||||
createdBy = citizen,
|
||||
target = constitution,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package feature
|
||||
|
||||
import fr.dcproject.entity.ArticleRef
|
||||
import fr.dcproject.component.article.ArticleRef
|
||||
import fr.dcproject.entity.ConstitutionRef
|
||||
import fr.dcproject.entity.Follow
|
||||
import fr.dcproject.entity.FollowForUpdate
|
||||
import fr.dcproject.utils.toUUID
|
||||
import io.cucumber.java8.En
|
||||
import org.koin.test.KoinTest
|
||||
@@ -16,13 +16,13 @@ class FollowSteps : En, KoinTest {
|
||||
Given("I have follow of {word} {word} on article {string}") { firstName: String, lastName: String, articleId: String ->
|
||||
val username = "$firstName-$lastName".toLowerCase()
|
||||
val citizen = get<CitizenRepository>().findByUsername(username) ?: error("Citizen not exist")
|
||||
val follow = Follow(createdBy = citizen, target = ArticleRef(articleId.toUUID()))
|
||||
val follow = FollowForUpdate(createdBy = citizen, target = ArticleRef(articleId.toUUID()))
|
||||
get<FollowArticleRepository>().follow(follow)
|
||||
}
|
||||
Given("I have follow of {word} {word} on constitution {string}") { firstName: String, lastName: String, constitutionId: String ->
|
||||
val username = "$firstName-$lastName".toLowerCase()
|
||||
val citizen = get<CitizenRepository>().findByUsername(username) ?: error("Citizen not exist")
|
||||
val follow = Follow(createdBy = citizen, target = ConstitutionRef(constitutionId.toUUID()))
|
||||
val follow = FollowForUpdate(createdBy = citizen, target = ConstitutionRef(constitutionId.toUUID()))
|
||||
get<FollowConstitutionRepository>().follow(follow)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package feature
|
||||
import com.auth0.jwt.JWT
|
||||
import fr.dcproject.JwtConfig
|
||||
import io.cucumber.java8.En
|
||||
import io.ktor.http.HttpHeaders
|
||||
import io.ktor.http.*
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.get
|
||||
import fr.dcproject.repository.Citizen as CitizenRepository
|
||||
|
||||
@@ -3,12 +3,9 @@ package feature
|
||||
import com.jayway.jsonpath.JsonPath
|
||||
import io.cucumber.datatable.DataTable
|
||||
import io.cucumber.java8.En
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.HttpHeaders
|
||||
import io.ktor.http.HttpMethod
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.testing.setBody
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import io.ktor.http.*
|
||||
import io.ktor.server.testing.*
|
||||
import io.ktor.util.*
|
||||
import kotlinx.serialization.ImplicitReflectionSerializer
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
@@ -42,7 +39,11 @@ class KtorServerRequestSteps : En {
|
||||
}
|
||||
|
||||
Then("the response status code should be {int}") { statusCode: Int ->
|
||||
assertEquals(HttpStatusCode.fromValue(statusCode), KtorServerContext.defaultServer.call?.response?.status())
|
||||
assertEquals(
|
||||
HttpStatusCode.fromValue(statusCode),
|
||||
KtorServerContext.defaultServer.call?.response?.status(),
|
||||
KtorServerContext.defaultServer.call?.response?.content
|
||||
)
|
||||
}
|
||||
|
||||
Then("the response should contain object:") { expected: DataTable ->
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package feature
|
||||
|
||||
import fr.dcproject.entity.OpinionArticle
|
||||
import fr.dcproject.component.article.ArticleRef
|
||||
import fr.dcproject.component.article.ArticleRepository
|
||||
import fr.dcproject.entity.OpinionChoice
|
||||
import fr.dcproject.entity.OpinionForUpdate
|
||||
import fr.dcproject.utils.toUUID
|
||||
import io.cucumber.datatable.DataTable
|
||||
import io.cucumber.java8.En
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.get
|
||||
import java.util.*
|
||||
import fr.dcproject.repository.Article as ArticleRepository
|
||||
import fr.dcproject.repository.Citizen as CitizenRepository
|
||||
import fr.dcproject.repository.OpinionArticle as OpinionRepository
|
||||
import fr.dcproject.repository.OpinionChoice as OpinionChoiceRepository
|
||||
@@ -52,11 +53,11 @@ class OpinionSteps : En, KoinTest {
|
||||
lastName: String,
|
||||
id: String? = null
|
||||
) {
|
||||
val opinion = OpinionArticle(
|
||||
val opinion = OpinionForUpdate(
|
||||
id = id?.toUUID() ?: UUID.randomUUID(),
|
||||
choice = get<OpinionChoiceRepository>().findOpinionsChoiceByName(opinionChoiceName)
|
||||
?: error("Opinion Choice not exist"),
|
||||
target = get<ArticleRepository>().findById(articleId.toUUID()) ?: error("Article not exist"),
|
||||
target = ArticleRef(articleId.toUUID()),
|
||||
createdBy = get<CitizenRepository>().findByUsername("$firstName-$lastName".toLowerCase().replace(' ', '-'))
|
||||
?: error("Citizen not exist")
|
||||
)
|
||||
@@ -67,7 +68,7 @@ class OpinionSteps : En, KoinTest {
|
||||
val params = extraInfo?.asMap<String, String>(String::class.java, String::class.java)
|
||||
val username = params?.get("createdBy")?.toLowerCase()?.replace(' ', '-')
|
||||
?: error("You must provide the 'createdBy' parameter")
|
||||
val opinion = OpinionArticle(
|
||||
val opinion = OpinionForUpdate(
|
||||
choice = params["opinion"]?.let {
|
||||
get<OpinionChoiceRepository>().findOpinionsChoiceByName(it) ?: error("Opinion Choice not exist")
|
||||
} ?: error("You must provide the 'opinion' parameter"),
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package feature
|
||||
|
||||
import fr.dcproject.entity.Vote
|
||||
import fr.dcproject.component.article.ArticleRepository
|
||||
import fr.dcproject.entity.VoteForUpdate
|
||||
import fr.dcproject.utils.toUUID
|
||||
import io.cucumber.java8.En
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.get
|
||||
import java.util.*
|
||||
import fr.dcproject.repository.Article as ArticleRepository
|
||||
import fr.dcproject.repository.Citizen as CitizenRepository
|
||||
import fr.dcproject.repository.VoteArticle as VoteRepository
|
||||
|
||||
@@ -22,7 +22,7 @@ class VoteSteps : En, KoinTest {
|
||||
}
|
||||
|
||||
private fun createVote(note: Int, articleId: String, firstName: String, lastName: String, id: String? = null) {
|
||||
val vote = Vote(
|
||||
val vote = VoteForUpdate(
|
||||
id = id?.toUUID() ?: UUID.randomUUID(),
|
||||
note = note,
|
||||
target = get<ArticleRepository>().findById(articleId.toUUID()) ?: error("Article not exist"),
|
||||
|
||||
@@ -30,7 +30,7 @@ class WorkgroupSteps : En, KoinTest {
|
||||
|
||||
val creator = data["created_by"]?.let {
|
||||
get<CitizenRepository>().findByUsername(it.toLowerCase().replace(' ', '-'))
|
||||
} ?: kotlin.run {
|
||||
} ?: run {
|
||||
val username = "paul-langevin".toLowerCase() + UUID.randomUUID()
|
||||
val user = User(
|
||||
username = username,
|
||||
@@ -46,12 +46,13 @@ class WorkgroupSteps : En, KoinTest {
|
||||
}
|
||||
}
|
||||
|
||||
val workgroup = WorkgroupSimple<CitizenRef>(
|
||||
val workgroup = Workgroup(
|
||||
id = UUID.fromString(data["id"] ?: UUID.randomUUID().toString()),
|
||||
name = data["name"] ?: "Les Incoruptible",
|
||||
description = data["description"] ?: "La vie est notre jeux",
|
||||
createdBy = creator,
|
||||
anonymous = (data["anonymous"] ?: false) == true
|
||||
anonymous = (data["anonymous"] ?: false) == true,
|
||||
members = listOf(Member(creator, listOf(Member.Role.MASTER)))
|
||||
)
|
||||
|
||||
get<WorkgroupRepository>().upsert(workgroup)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.citizenOrNull
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.can
|
||||
import fr.ktorVoter.canAll
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.component.article.ArticleVoter
|
||||
import fr.dcproject.entity.CitizenCart
|
||||
import fr.dcproject.entity.CitizenI
|
||||
import fr.dcproject.entity.User
|
||||
import fr.dcproject.entity.UserI
|
||||
import fr.dcproject.voter.Vote.DENIED
|
||||
import fr.dcproject.voter.Vote.GRANTED
|
||||
import fr.postgresjson.connexion.Paginated
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
@@ -16,33 +17,31 @@ import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Tag
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import fr.dcproject.repository.Article as ArticleRepo
|
||||
import java.util.*
|
||||
import fr.dcproject.component.article.ArticleRepository as ArticleRepo
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@Tag("voter")
|
||||
class ArticleVoterTest {
|
||||
private val tesla = Citizen(
|
||||
private val tesla = CitizenCart(
|
||||
id = UUID.fromString("e6efc288-4283-4729-a268-6debb18de1a0"),
|
||||
user = User(
|
||||
username = "nicolas-tesla",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
),
|
||||
birthday = DateTime.now(),
|
||||
email = "tesla@best.com",
|
||||
name = CitizenI.Name("Nicolas", "Tesla")
|
||||
)
|
||||
private val einstein = Citizen(
|
||||
private val einstein = CitizenCart(
|
||||
user = User(
|
||||
username = "albert-einstein",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
),
|
||||
birthday = DateTime.now(),
|
||||
email = "einstein@best.com",
|
||||
name = CitizenI.Name("Albert", "Einstein")
|
||||
)
|
||||
|
||||
private fun getRepo(article: Article): ArticleRepo {
|
||||
private fun getRepo(article: ArticleForView): ArticleRepo {
|
||||
return mockk {
|
||||
every { findVerionsByVersionsId(1, 1, any()) } returns Paginated(listOf(article), 0, 1, 1)
|
||||
every { findVersionsByVersionId(1, 1, any()) } returns Paginated(listOf(article), 0, 1, 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,26 +50,19 @@ class ArticleVoterTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `creator can be view the article`(): Unit {
|
||||
val article = getArticle(tesla).apply { draft = true }
|
||||
ArticleVoter(getRepo(article)).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
this(ArticleVoter.Action.VIEW, it, article) `should be` Vote.GRANTED
|
||||
}
|
||||
}
|
||||
fun `creator can be view the article`() {
|
||||
val article = getArticle(tesla).copy(draft = true)
|
||||
ArticleVoter(getRepo(article))
|
||||
.canView(article, tesla)
|
||||
.vote `should be` GRANTED
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `other user can be view the article`(): Unit = listOf(ArticleVoter(mockk())).run {
|
||||
fun `other user can be view the article`() {
|
||||
val article = getArticle(tesla)
|
||||
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
}.let {
|
||||
can(ArticleVoter.Action.VIEW, it, article) `should be` true
|
||||
}
|
||||
ArticleVoter(getRepo(article))
|
||||
.canView(article, einstein)
|
||||
.vote `should be` GRANTED
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -78,121 +70,93 @@ class ArticleVoterTest {
|
||||
val article = getArticle(tesla)
|
||||
val article2 = getArticle(tesla)
|
||||
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
}.let {
|
||||
canAll(ArticleVoter.Action.VIEW, it, listOf(article, article2)) `should be` true
|
||||
}
|
||||
ArticleVoter(getRepo(article))
|
||||
.canView(listOf(article, article2), einstein)
|
||||
.vote `should be` GRANTED
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `the no creator can not be view the article on draft`(): Unit = listOf(ArticleVoter(mockk())).run {
|
||||
val article = getArticle(tesla).apply { draft = true }
|
||||
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
}.let {
|
||||
can(ArticleVoter.Action.VIEW, it, article) `should be` false
|
||||
}
|
||||
fun `the no creator can not be view the article on draft`() {
|
||||
val article = getArticle(tesla).copy(draft = true)
|
||||
ArticleVoter(getRepo(article))
|
||||
.canView(article, einstein)
|
||||
.vote `should be` DENIED
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `the no creator can not be view list of articles if one is on draft`(): Unit = listOf(ArticleVoter(mockk())).run {
|
||||
fun `the no creator can not be view list of articles if one is on draft`() {
|
||||
val article = getArticle(tesla)
|
||||
val article2 = getArticle(tesla).apply { draft = true }
|
||||
val article2 = getArticle(tesla).copy(draft = true)
|
||||
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
}.let {
|
||||
canAll(ArticleVoter.Action.VIEW, it, listOf(article, article2)) `should be` false
|
||||
}
|
||||
ArticleVoter(getRepo(article))
|
||||
.canView(listOf(article, article2), einstein)
|
||||
.vote `should be` DENIED
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can not view deleted article`(): Unit = listOf(ArticleVoter(mockk())).run {
|
||||
val article = getArticle(tesla).apply { deletedAt = DateTime.now() }
|
||||
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
can(ArticleVoter.Action.VIEW, it, article) `should be` false
|
||||
}
|
||||
fun `can not view deleted article`() {
|
||||
val article = getArticle(tesla).copy(deletedAt = DateTime.now())
|
||||
ArticleVoter(getRepo(article))
|
||||
.canView(article, tesla)
|
||||
.vote `should be` DENIED
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can delete article if owner`(): Unit = listOf(ArticleVoter(mockk())).run {
|
||||
fun `can delete article if owner`() {
|
||||
val article = getArticle(tesla)
|
||||
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
can(ArticleVoter.Action.DELETE, it, article) `should be` true
|
||||
}
|
||||
ArticleVoter(getRepo(article))
|
||||
.canDelete(article, tesla)
|
||||
.vote `should be` GRANTED
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can not delete article if not owner`(): Unit = listOf(ArticleVoter(mockk())).run {
|
||||
val article = getArticle(tesla).apply { deletedAt = DateTime.now() }
|
||||
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
}.let {
|
||||
can(ArticleVoter.Action.DELETE, it, article) `should be` false
|
||||
}
|
||||
fun `can not delete article if not owner`() {
|
||||
val article = getArticle(tesla).copy(deletedAt = DateTime.now())
|
||||
ArticleVoter(getRepo(article))
|
||||
.canDelete(article, einstein)
|
||||
.code `should be` "article.delete.notYours"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can create article if logged`(): Unit = listOf(ArticleVoter(mockk())).run {
|
||||
fun `can create article if logged`() {
|
||||
val article = getArticle(tesla)
|
||||
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
can(ArticleVoter.Action.CREATE, it, article) `should be` true
|
||||
}
|
||||
ArticleVoter(getRepo(article))
|
||||
.canUpsert(article, tesla)
|
||||
.vote `should be` GRANTED
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can not create article if not logged`(): Unit = listOf(ArticleVoter(mockk())).run {
|
||||
fun `can not create article if not logged`() {
|
||||
val article = getArticle(tesla)
|
||||
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns null
|
||||
}.let {
|
||||
can(ArticleVoter.Action.CREATE, it, article) `should be` false
|
||||
}
|
||||
ArticleVoter(getRepo(article))
|
||||
.canUpsert(article, null)
|
||||
.code `should be` "article.create.notConnected"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can update article if yours`(): Unit {
|
||||
val article = getArticle(tesla)
|
||||
listOf(ArticleVoter(getRepo(article))).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
can(ArticleVoter.Action.UPDATE, it, article) `should be` true
|
||||
}
|
||||
}
|
||||
ArticleVoter(getRepo(article))
|
||||
.canUpsert(article, tesla)
|
||||
.vote `should be` GRANTED
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can not update article if not yours`(): Unit {
|
||||
val article = getArticle(tesla)
|
||||
listOf(ArticleVoter(getRepo(article))).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
every { citizenOrNull } returns einstein
|
||||
}.let {
|
||||
can(ArticleVoter.Action.UPDATE, it, article) `should be` false
|
||||
}
|
||||
}
|
||||
ArticleVoter(getRepo(article))
|
||||
.canUpsert(article, einstein)
|
||||
.code `should be` "article.update.notYours"
|
||||
}
|
||||
|
||||
private fun getArticle(createdBy: CitizenBasic = tesla) = Article(
|
||||
private fun getArticle(createdBy: CitizenCart = tesla) = ArticleForView(
|
||||
id = UUID.randomUUID(),
|
||||
title = "Hello world",
|
||||
content = "Super",
|
||||
description = "I Rocks",
|
||||
createdBy = createdBy
|
||||
createdBy = createdBy,
|
||||
opinions = mapOf(),
|
||||
versionId = UUID.randomUUID(),
|
||||
versionNumber = 1
|
||||
)
|
||||
}
|
||||
@@ -5,12 +5,9 @@ import fr.dcproject.entity.CitizenI
|
||||
import fr.dcproject.entity.User
|
||||
import fr.dcproject.entity.UserI
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.can
|
||||
import fr.ktorVoter.canAll
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import fr.ktorVoter.*
|
||||
import io.ktor.application.*
|
||||
import io.ktor.locations.*
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
@@ -19,6 +16,7 @@ import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Tag
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@@ -50,8 +48,9 @@ class CitizenVoterTest {
|
||||
),
|
||||
birthday = DateTime.now(),
|
||||
email = "curie@best.com",
|
||||
name = CitizenI.Name("Marie", "Curie")
|
||||
).apply { deletedAt = DateTime.now() }
|
||||
name = CitizenI.Name("Marie", "Curie"),
|
||||
deletedAt = DateTime.now()
|
||||
)
|
||||
|
||||
init {
|
||||
mockkStatic("fr.dcproject.ApplicationContextKt")
|
||||
@@ -63,8 +62,8 @@ class CitizenVoterTest {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
this(CitizenVoter.Action.VIEW, it, einstein) `should be` Vote.GRANTED
|
||||
this(p, it, einstein) `should be` Vote.ABSTAIN
|
||||
this(CitizenVoter.Action.VIEW, it, einstein).vote `should be` Vote.GRANTED
|
||||
this(p, it, einstein).vote `should be` Vote.ABSTAIN
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +108,9 @@ class CitizenVoterTest {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
}.let {
|
||||
can(CitizenVoter.Action.UPDATE, it, tesla) `should be` false
|
||||
assertThrows<OneOrMoreVoterDeniedException> {
|
||||
assertCan(CitizenVoter.Action.UPDATE, it, tesla)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.citizenOrNull
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.component.article.ArticleRef
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.dcproject.voter.NoSubjectDefinedException
|
||||
import fr.ktorVoter.*
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.can
|
||||
import fr.ktorVoter.canAll
|
||||
import fr.postgresjson.connexion.Paginated
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.application.*
|
||||
import io.ktor.locations.*
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
@@ -17,13 +18,15 @@ import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Tag
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import fr.dcproject.repository.Article as ArticleRepo
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import java.util.*
|
||||
import fr.dcproject.component.article.ArticleRepository as ArticleRepo
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@Tag("voter")
|
||||
internal class CommentVoterTest {
|
||||
private val tesla = CitizenBasic(
|
||||
private val tesla = Citizen(
|
||||
user = User(
|
||||
username = "nicolas-tesla",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
@@ -32,7 +35,8 @@ internal class CommentVoterTest {
|
||||
email = "tesla@best.com",
|
||||
name = CitizenI.Name("Nicolas", "Tesla")
|
||||
)
|
||||
private val einstein = CitizenBasic(
|
||||
private val einstein = Citizen(
|
||||
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
|
||||
user = User(
|
||||
username = "albert-einstein",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
@@ -42,45 +46,60 @@ internal class CommentVoterTest {
|
||||
name = CitizenI.Name("Albert", "Einstein")
|
||||
)
|
||||
|
||||
private val article1 = Article(
|
||||
private val einstein2 = CitizenCart(
|
||||
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
|
||||
user = User(
|
||||
username = "albert-einstein",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
),
|
||||
name = CitizenI.Name("Albert", "Einstein")
|
||||
)
|
||||
|
||||
private val article1 = ArticleForView(
|
||||
content = "Hi",
|
||||
createdBy = einstein,
|
||||
createdBy = einstein2,
|
||||
description = "blablabla",
|
||||
title = "Super article"
|
||||
)
|
||||
|
||||
private val comment1 = Comment(
|
||||
private val comment1 = CommentForView(
|
||||
content = "Hello",
|
||||
createdBy = tesla,
|
||||
target = article1
|
||||
)
|
||||
|
||||
private val comment2 = Comment(
|
||||
private val commentForUpdate = CommentForUpdate(
|
||||
content = "Hello",
|
||||
createdBy = tesla,
|
||||
target = article1
|
||||
)
|
||||
|
||||
private val comment2 = CommentForView(
|
||||
content = "Hello2",
|
||||
createdBy = einstein,
|
||||
target = article1
|
||||
)
|
||||
|
||||
private val commentTargetDeleted = Comment(
|
||||
private val commentTargetDeleted = CommentForView(
|
||||
content = "Hello",
|
||||
createdBy = tesla,
|
||||
target = Article(
|
||||
target = ArticleForView(
|
||||
content = "Hi",
|
||||
createdBy = einstein,
|
||||
createdBy = einstein2,
|
||||
description = "blablabla",
|
||||
title = "Super article",
|
||||
workgroup = null
|
||||
).apply { deletedAt = DateTime.now() }
|
||||
).copy(deletedAt = DateTime.now())
|
||||
)
|
||||
|
||||
private val commentTargetNoUser = Comment(
|
||||
private val commentTargetNoUser = CommentForView(
|
||||
content = "Hello",
|
||||
createdBy = tesla,
|
||||
target = ArticleRef()
|
||||
)
|
||||
|
||||
private val repoArticle1 = mockk<ArticleRepo> {
|
||||
every { findVerionsByVersionsId(1, 1, any()) } returns Paginated(listOf(article1), 0, 1, 1)
|
||||
every { findVersionsByVersionId(1, 1, any()) } returns Paginated(listOf(article1), 0, 1, 1)
|
||||
}
|
||||
|
||||
init {
|
||||
@@ -91,19 +110,19 @@ internal class CommentVoterTest {
|
||||
fun `support comment`(): Unit = CommentVoter().run {
|
||||
val p = object : ActionI {}
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
this(CommentVoter.Action.VIEW, it, comment1) `should be` Vote.GRANTED
|
||||
this(CommentVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN
|
||||
this(p, it, comment1) `should be` Vote.ABSTAIN
|
||||
this(CommentVoter.Action.VIEW, it, comment1).vote `should be` Vote.GRANTED
|
||||
this(CommentVoter.Action.VIEW, it, article1).vote `should be` Vote.ABSTAIN
|
||||
this(p, it, comment1).vote `should be` Vote.ABSTAIN
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can be view the comment`(): Unit {
|
||||
listOf(CommentVoter(), ArticleVoter(repoArticle1)).run {
|
||||
listOf(CommentVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
can(CommentVoter.Action.VIEW, it, comment1) `should be` true
|
||||
}
|
||||
@@ -113,7 +132,7 @@ internal class CommentVoterTest {
|
||||
@Test
|
||||
fun `can be view the comment list`(): Unit = listOf(CommentVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
every { citizenOrNull } returns einstein
|
||||
}.let {
|
||||
canAll(CommentVoter.Action.VIEW, it, listOf(comment1)) `should be` true
|
||||
}
|
||||
@@ -122,7 +141,7 @@ internal class CommentVoterTest {
|
||||
@Test
|
||||
fun `can be update your comment`(): Unit = listOf(CommentVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
can(CommentVoter.Action.UPDATE, it, comment1) `should be` true
|
||||
}
|
||||
@@ -131,7 +150,7 @@ internal class CommentVoterTest {
|
||||
@Test
|
||||
fun `can not be update other comment`(): Unit = listOf(CommentVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
every { citizenOrNull } returns einstein
|
||||
}.let {
|
||||
can(CommentVoter.Action.UPDATE, it, comment1) `should be` false
|
||||
}
|
||||
@@ -140,43 +159,34 @@ internal class CommentVoterTest {
|
||||
@Test
|
||||
fun `can not be delete your comment`(): Unit = listOf(CommentVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
can(CommentVoter.Action.DELETE, it, comment1) `should be` false
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can be create a comment`(): Unit = listOf(CommentVoter(), ArticleVoter(repoArticle1)).run {
|
||||
fun `can be create a comment`(): Unit = listOf(CommentVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
can(CommentVoter.Action.CREATE, it, comment1) `should be` true
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can not be create a comment if target is deleted`(): Unit = listOf(CommentVoter(), ArticleVoter(repoArticle1)).run {
|
||||
fun `can not be create a comment if target is deleted`(): Unit = listOf(CommentVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
can(CommentVoter.Action.CREATE, it, commentTargetDeleted) `should be` false
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can not be create a comment if target has no user`(): Unit = listOf(CommentVoter(), ArticleVoter(repoArticle1)).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
can(CommentVoter.Action.CREATE, it, commentTargetNoUser) `should be` false
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can not be create a comment with other creator`(): Unit = listOf(CommentVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
every { citizenOrNull } returns einstein
|
||||
}.let {
|
||||
can(CommentVoter.Action.CREATE, it, comment1) `should be` false
|
||||
}
|
||||
@@ -185,16 +195,18 @@ internal class CommentVoterTest {
|
||||
@Test
|
||||
fun `can not be create a comment if is null`(): Unit = listOf(CommentVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
every { citizenOrNull } returns einstein
|
||||
}.let {
|
||||
can(CommentVoter.Action.CREATE, it, null) `should be` false
|
||||
assertThrows<NoSubjectDefinedException> {
|
||||
assertCan(CommentVoter.Action.CREATE, it, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can not be create a comment if not connected`(): Unit = listOf(CommentVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns null
|
||||
every { citizenOrNull } returns null
|
||||
}.let {
|
||||
can(CommentVoter.Action.CREATE, it, comment1) `should be` false
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.citizenOrNull
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.dcproject.voter.NoSubjectDefinedException
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.can
|
||||
import fr.ktorVoter.canAll
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.application.*
|
||||
import io.ktor.locations.*
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
@@ -16,6 +18,8 @@ import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Tag
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import java.util.*
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@@ -31,8 +35,19 @@ internal class FollowVoterTest {
|
||||
name = CitizenI.Name("Nicolas", "Tesla"),
|
||||
followAnonymous = false
|
||||
)
|
||||
private val tesla2 = Citizen(
|
||||
user = User(
|
||||
username = "nicolas-tesla",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
),
|
||||
birthday = DateTime.now(),
|
||||
email = "tesla@best.com",
|
||||
name = CitizenI.Name("Nicolas", "Tesla"),
|
||||
followAnonymous = false
|
||||
)
|
||||
|
||||
private val einstein = CitizenBasic(
|
||||
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
|
||||
user = User(
|
||||
username = "albert-einstein",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
@@ -43,9 +58,30 @@ internal class FollowVoterTest {
|
||||
followAnonymous = true
|
||||
)
|
||||
|
||||
private val article1 = Article(
|
||||
private val einstein2 = CitizenCart(
|
||||
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
|
||||
user = User(
|
||||
username = "albert-einstein",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
),
|
||||
name = CitizenI.Name("Albert", "Einstein")
|
||||
)
|
||||
|
||||
private val einstein3 = Citizen(
|
||||
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
|
||||
user = User(
|
||||
username = "albert-einstein",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
),
|
||||
birthday = DateTime.now(),
|
||||
email = "einstein@best.com",
|
||||
name = CitizenI.Name("Albert", "Einstein"),
|
||||
followAnonymous = true
|
||||
)
|
||||
|
||||
private val article1 = ArticleForView(
|
||||
content = "Hi",
|
||||
createdBy = einstein,
|
||||
createdBy = einstein2,
|
||||
description = "blablabla",
|
||||
title = "Super article"
|
||||
)
|
||||
@@ -68,18 +104,20 @@ internal class FollowVoterTest {
|
||||
fun `support follow`(): Unit = FollowVoter().run {
|
||||
val p = object : ActionI {}
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla2
|
||||
}.let {
|
||||
this(FollowVoter.Action.VIEW, it, follow1) `should be` Vote.GRANTED
|
||||
this(FollowVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN
|
||||
this(p, it, follow1) `should be` Vote.ABSTAIN
|
||||
this(FollowVoter.Action.VIEW, it, follow1).vote `should be` Vote.GRANTED
|
||||
assertThrows<NoSubjectDefinedException> {
|
||||
this(FollowVoter.Action.VIEW, it, article1)
|
||||
}
|
||||
this(p, it, follow1).vote `should be` Vote.ABSTAIN
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can be view the follow`(): Unit = listOf(FollowVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla2
|
||||
}.let {
|
||||
can(FollowVoter.Action.VIEW, it, follow1) `should be` true
|
||||
}
|
||||
@@ -88,7 +126,7 @@ internal class FollowVoterTest {
|
||||
@Test
|
||||
fun `can be view the follow list`(): Unit = listOf(FollowVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla2
|
||||
}.let {
|
||||
canAll(FollowVoter.Action.VIEW, it, listOf(follow1)) `should be` true
|
||||
}
|
||||
@@ -97,7 +135,7 @@ internal class FollowVoterTest {
|
||||
@Test
|
||||
fun `can be view your anonymous follow`(): Unit = listOf(FollowVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
every { citizenOrNull } returns einstein3
|
||||
}.let {
|
||||
can(FollowVoter.Action.VIEW, it, followAnon) `should be` true
|
||||
}
|
||||
@@ -106,7 +144,7 @@ internal class FollowVoterTest {
|
||||
@Test
|
||||
fun `can not be view the anonymous follow of other`(): Unit = listOf(FollowVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla2
|
||||
}.let {
|
||||
can(FollowVoter.Action.VIEW, it, followAnon) `should be` false
|
||||
}
|
||||
@@ -115,7 +153,7 @@ internal class FollowVoterTest {
|
||||
@Test
|
||||
fun `can be follow article`(): Unit = listOf(FollowVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla2
|
||||
}.let {
|
||||
can(FollowVoter.Action.CREATE, it, follow1) `should be` true
|
||||
}
|
||||
@@ -124,7 +162,7 @@ internal class FollowVoterTest {
|
||||
@Test
|
||||
fun `can not be follow article if not connected`(): Unit = listOf(FollowVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns null
|
||||
every { citizenOrNull } returns null
|
||||
}.let {
|
||||
can(FollowVoter.Action.CREATE, it, follow1) `should be` false
|
||||
}
|
||||
@@ -133,7 +171,7 @@ internal class FollowVoterTest {
|
||||
@Test
|
||||
fun `can be unfollow article`(): Unit = listOf(FollowVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla2
|
||||
}.let {
|
||||
can(FollowVoter.Action.DELETE, it, follow1) `should be` true
|
||||
}
|
||||
@@ -142,7 +180,7 @@ internal class FollowVoterTest {
|
||||
@Test
|
||||
fun `can not be unfollow article if not connected`(): Unit = listOf(FollowVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns null
|
||||
every { citizenOrNull } returns null
|
||||
}.let {
|
||||
can(FollowVoter.Action.DELETE, it, follow1) `should be` false
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.can
|
||||
import fr.ktorVoter.canAll
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.application.*
|
||||
import io.ktor.locations.*
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
@@ -16,12 +17,14 @@ import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Tag
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import java.util.*
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@Tag("voter")
|
||||
internal class OpinionChoiceVoterTest {
|
||||
private val tesla = CitizenBasic(
|
||||
id = UUID.fromString("e6efc288-4283-4729-a268-6debb18de1a0"),
|
||||
user = User(
|
||||
username = "nicolas-tesla",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
@@ -32,9 +35,18 @@ internal class OpinionChoiceVoterTest {
|
||||
followAnonymous = false
|
||||
)
|
||||
|
||||
private val article1 = Article(
|
||||
private val tesla2 = CitizenCart(
|
||||
id = UUID.fromString("e6efc288-4283-4729-a268-6debb18de1a0"),
|
||||
user = User(
|
||||
username = "nicolas-tesla",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
),
|
||||
name = CitizenI.Name("Nicolas", "Tesla")
|
||||
)
|
||||
|
||||
private val article1 = ArticleForView(
|
||||
content = "Hi",
|
||||
createdBy = tesla,
|
||||
createdBy = tesla2,
|
||||
description = "blablabla",
|
||||
title = "Super article"
|
||||
)
|
||||
@@ -54,9 +66,9 @@ internal class OpinionChoiceVoterTest {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
this(OpinionChoiceVoter.Action.VIEW, it, choice1) `should be` Vote.GRANTED
|
||||
this(OpinionChoiceVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN
|
||||
this(p, it, choice1) `should be` Vote.ABSTAIN
|
||||
this(OpinionChoiceVoter.Action.VIEW, it, choice1).vote `should be` Vote.GRANTED
|
||||
this(OpinionChoiceVoter.Action.VIEW, it, article1).vote `should be` Vote.ABSTAIN
|
||||
this(p, it, choice1).vote `should be` Vote.ABSTAIN
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.dcproject.voter.NoSubjectDefinedException
|
||||
import fr.ktorVoter.*
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.can
|
||||
import fr.ktorVoter.canAll
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.application.*
|
||||
import io.ktor.locations.*
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
@@ -16,6 +16,8 @@ import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Tag
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import java.util.*
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@@ -33,6 +35,7 @@ internal class OpinionVoterTest {
|
||||
)
|
||||
|
||||
private val einstein = CitizenBasic(
|
||||
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
|
||||
user = User(
|
||||
username = "albert-einstein",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
@@ -43,9 +46,18 @@ internal class OpinionVoterTest {
|
||||
followAnonymous = true
|
||||
)
|
||||
|
||||
private val article1 = Article(
|
||||
private val einstein2 = CitizenCart(
|
||||
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
|
||||
user = User(
|
||||
username = "albert-einstein",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
),
|
||||
name = CitizenI.Name("Albert", "Einstein")
|
||||
)
|
||||
|
||||
private val article1 = ArticleForView(
|
||||
content = "Hi",
|
||||
createdBy = einstein,
|
||||
createdBy = einstein2,
|
||||
description = "blablabla",
|
||||
title = "Super article"
|
||||
)
|
||||
@@ -69,10 +81,10 @@ internal class OpinionVoterTest {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
this(OpinionVoter.Action.VIEW, it, opinion1) `should be` Vote.GRANTED
|
||||
this(OpinionVoter.Action.VIEW, it, article1) `should be` Vote.GRANTED
|
||||
this(OpinionVoter.Action.VIEW, it, einstein) `should be` Vote.ABSTAIN
|
||||
this(p, it, opinion1) `should be` Vote.ABSTAIN
|
||||
this(OpinionVoter.Action.VIEW, it, opinion1).vote `should be` Vote.GRANTED
|
||||
this(OpinionVoter.Action.VIEW, it, article1).vote `should be` Vote.GRANTED
|
||||
this(OpinionVoter.Action.VIEW, it, einstein).vote `should be` Vote.ABSTAIN
|
||||
this(p, it, opinion1).vote `should be` Vote.ABSTAIN
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +102,9 @@ internal class OpinionVoterTest {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
can(OpinionVoter.Action.VIEW, it, null) `should be` false
|
||||
assertThrows<NoSubjectDefinedException> {
|
||||
assertCan(OpinionVoter.Action.VIEW, it, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.citizenOrNull
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.component.article.ArticleRef
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.dcproject.voter.NoSubjectDefinedException
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.can
|
||||
import fr.ktorVoter.canAll
|
||||
import fr.postgresjson.connexion.Paginated
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.application.*
|
||||
import io.ktor.locations.*
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
@@ -17,13 +19,27 @@ import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Tag
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import java.util.*
|
||||
import fr.dcproject.entity.Vote as VoteEntity
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@Tag("voter")
|
||||
internal class VoteVoterTest {
|
||||
private val tesla = CitizenBasic(
|
||||
private val tesla = Citizen(
|
||||
id = UUID.fromString("a1e35c99-9d33-4fb4-9201-58d7071243bb"),
|
||||
user = User(
|
||||
username = "nicolas-tesla",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
),
|
||||
birthday = DateTime.now(),
|
||||
email = "tesla@best.com",
|
||||
name = CitizenI.Name("Nicolas", "Tesla"),
|
||||
followAnonymous = false
|
||||
)
|
||||
private val tesla3 = CitizenBasic(
|
||||
id = UUID.fromString("a1e35c99-9d33-4fb4-9201-58d7071243bb"),
|
||||
user = User(
|
||||
username = "nicolas-tesla",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
@@ -34,7 +50,8 @@ internal class VoteVoterTest {
|
||||
followAnonymous = false
|
||||
)
|
||||
|
||||
private val einstein = CitizenBasic(
|
||||
private val einstein = Citizen(
|
||||
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
|
||||
user = User(
|
||||
username = "albert-einstein",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
@@ -45,31 +62,46 @@ internal class VoteVoterTest {
|
||||
followAnonymous = true
|
||||
)
|
||||
|
||||
private val article1 = Article(
|
||||
private val einstein2 = CitizenCart(
|
||||
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
|
||||
user = User(
|
||||
username = "albert-einstein",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
),
|
||||
name = CitizenI.Name("Albert", "Einstein")
|
||||
)
|
||||
|
||||
private val article1 = ArticleForView(
|
||||
content = "Hi",
|
||||
createdBy = einstein,
|
||||
createdBy = einstein2,
|
||||
description = "blablabla",
|
||||
title = "Super article"
|
||||
)
|
||||
|
||||
private val vote1 = VoteEntity(
|
||||
createdBy = tesla3,
|
||||
target = article1,
|
||||
note = 1
|
||||
)
|
||||
|
||||
private val voteForUpdate = VoteForUpdate(
|
||||
createdBy = tesla,
|
||||
target = article1,
|
||||
note = 1
|
||||
)
|
||||
|
||||
private val voteOnDeleted = VoteEntity(
|
||||
private val voteOnDeleted = VoteForUpdate(
|
||||
createdBy = tesla,
|
||||
target = Article(
|
||||
target = ArticleForView(
|
||||
content = "Hi",
|
||||
createdBy = einstein,
|
||||
createdBy = einstein2,
|
||||
description = "blablabla",
|
||||
title = "Super article"
|
||||
).apply { deletedAt = DateTime.now() },
|
||||
).copy(deletedAt = DateTime.now()),
|
||||
note = 1
|
||||
)
|
||||
|
||||
private val voteWithoutUser = VoteEntity(
|
||||
private val voteWithoutTargetUser = VoteForUpdate(
|
||||
createdBy = tesla,
|
||||
target = ArticleRef(),
|
||||
note = 1
|
||||
@@ -83,18 +115,18 @@ internal class VoteVoterTest {
|
||||
fun `support vote`(): Unit = VoteVoter().run {
|
||||
val p = object : ActionI {}
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
this(VoteVoter.Action.VIEW, it, vote1) `should be` Vote.GRANTED
|
||||
this(VoteVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN
|
||||
this(p, it, vote1) `should be` Vote.ABSTAIN
|
||||
this(VoteVoter.Action.VIEW, it, vote1).vote `should be` Vote.GRANTED
|
||||
this(VoteVoter.Action.VIEW, it, article1).vote `should be` Vote.ABSTAIN
|
||||
this(p, it, vote1).vote `should be` Vote.ABSTAIN
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can be view your the vote`(): Unit = listOf(VoteVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
can(VoteVoter.Action.VIEW, it, vote1) `should be` true
|
||||
}
|
||||
@@ -103,7 +135,7 @@ internal class VoteVoterTest {
|
||||
@Test
|
||||
fun `can not be view vote of other`(): Unit = listOf(VoteVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns einstein.user
|
||||
every { citizenOrNull } returns einstein
|
||||
}.let {
|
||||
can(VoteVoter.Action.VIEW, it, vote1) `should be` false
|
||||
}
|
||||
@@ -112,16 +144,18 @@ internal class VoteVoterTest {
|
||||
@Test
|
||||
fun `can be not view the vote if is null`(): Unit = listOf(VoteVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
can(VoteVoter.Action.VIEW, it, null) `should be` false
|
||||
assertThrows<NoSubjectDefinedException> {
|
||||
can(VoteVoter.Action.VIEW, it, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can be view your votes list`(): Unit = listOf(VoteVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
canAll(VoteVoter.Action.VIEW, it, listOf(vote1)) `should be` true
|
||||
}
|
||||
@@ -129,11 +163,11 @@ internal class VoteVoterTest {
|
||||
|
||||
@Test
|
||||
fun `can be vote an article`(): Unit {
|
||||
listOf(VoteVoter(), ArticleVoter(mockk())).run {
|
||||
listOf(VoteVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
can(VoteVoter.Action.CREATE, it, vote1) `should be` true
|
||||
can(VoteVoter.Action.CREATE, it, voteForUpdate) `should be` true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,36 +175,38 @@ internal class VoteVoterTest {
|
||||
@Test
|
||||
fun `can not be vote if not connected`(): Unit = listOf(VoteVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns null
|
||||
every { citizenOrNull } returns null
|
||||
}.let {
|
||||
can(VoteVoter.Action.CREATE, it, vote1) `should be` false
|
||||
can(VoteVoter.Action.CREATE, it, voteForUpdate) `should be` false
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can not be vote an article if article is deleted`(): Unit = listOf(VoteVoter(), ArticleVoter(mockk())).run {
|
||||
fun `can not be vote an article if article is deleted`(): Unit = listOf(VoteVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
can(VoteVoter.Action.CREATE, it, voteOnDeleted) `should be` false
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can not be vote an article if article have no user`(): Unit = listOf(VoteVoter(), ArticleVoter(mockk())).run {
|
||||
fun `can not be vote an article if article have no user`(): Unit = listOf(VoteVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
can(VoteVoter.Action.CREATE, it, voteWithoutUser) `should be` false
|
||||
assertThrows<NoSubjectDefinedException> {
|
||||
can(VoteVoter.Action.CREATE, it, voteWithoutTargetUser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can not be comment an article if article is deleted`(): Unit = listOf(VoteVoter(), ArticleVoter(mockk())).run {
|
||||
fun `can not be comment an article if article is deleted`(): Unit = listOf(VoteVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
every { citizenOrNull } returns tesla
|
||||
}.let {
|
||||
can(CommentVoter.Action.CREATE, it, voteOnDeleted) `should be` false
|
||||
can(VoteVoter.Action.CREATE, it, voteOnDeleted) `should be` false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,22 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.dcproject.voter.NoSubjectDefinedException
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.VoterException
|
||||
import fr.ktorVoter.can
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.application.*
|
||||
import io.ktor.locations.*
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import org.amshove.kluent.`should be`
|
||||
import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Tag
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.api.*
|
||||
import java.util.*
|
||||
import fr.dcproject.entity.Workgroup as WorkgroupEntity
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@@ -35,6 +35,7 @@ internal class WorkgroupVoterTest {
|
||||
)
|
||||
|
||||
private val einstein = CitizenBasic(
|
||||
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
|
||||
user = User(
|
||||
username = "albert-einstein",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
@@ -45,9 +46,18 @@ internal class WorkgroupVoterTest {
|
||||
followAnonymous = true
|
||||
)
|
||||
|
||||
private val article1 = Article(
|
||||
private val einstein2 = CitizenCart(
|
||||
id = UUID.fromString("319f1226-8f47-4df3-babd-2c7671ad0fbc"),
|
||||
user = User(
|
||||
username = "albert-einstein",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
),
|
||||
name = CitizenI.Name("Albert", "Einstein")
|
||||
)
|
||||
|
||||
private val article1 = ArticleForView(
|
||||
content = "Hi",
|
||||
createdBy = einstein,
|
||||
createdBy = einstein2,
|
||||
description = "blablabla",
|
||||
title = "Super article"
|
||||
)
|
||||
@@ -80,9 +90,9 @@ internal class WorkgroupVoterTest {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
this(WorkgroupVoter.Action.VIEW, it, workgroupPublic) `should be` Vote.GRANTED
|
||||
this(WorkgroupVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN
|
||||
this(p, it, workgroupPublic) `should be` Vote.ABSTAIN
|
||||
this(WorkgroupVoter.Action.VIEW, it, workgroupPublic).vote `should be` Vote.GRANTED
|
||||
this(WorkgroupVoter.Action.VIEW, it, article1).vote `should be` Vote.ABSTAIN
|
||||
this(p, it, workgroupPublic).vote `should be` Vote.ABSTAIN
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +137,9 @@ internal class WorkgroupVoterTest {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
can(WorkgroupVoter.Action.VIEW, it, null) `should be` false
|
||||
assertThrows<NoSubjectDefinedException> {
|
||||
can(WorkgroupVoter.Action.VIEW, it, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user