Move tests and create a command to run all tests

This commit is contained in:
2021-01-15 02:40:41 +01:00
parent 7c106f7cf8
commit 459397f8e7
40 changed files with 160 additions and 66 deletions

View File

@@ -0,0 +1,165 @@
package unit.voter
import fr.dcproject.component.article.ArticleForView
import fr.dcproject.component.article.ArticleVoter
import fr.dcproject.component.citizen.CitizenCart
import fr.dcproject.component.citizen.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.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.Tag
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.parallel.Execution
import org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT
import java.util.*
import fr.dcproject.component.article.ArticleRepository as ArticleRepo
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Execution(CONCURRENT)
@Tag("voter")
internal class ArticleVoterTest {
private val tesla = 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 einstein = CitizenCart(
user = User(
username = "albert-einstein",
roles = listOf(UserI.Roles.ROLE_USER)
),
name = CitizenI.Name("Albert", "Einstein")
)
private fun getRepo(article: ArticleForView): ArticleRepo {
return mockk {
every { findVersionsByVersionId(1, 1, any()) } returns Paginated(listOf(article), 0, 1, 1)
}
}
init {
mockkStatic("fr.dcproject.ApplicationContextKt")
}
@Test
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`() {
val article = getArticle(tesla)
ArticleVoter(getRepo(article))
.canView(article, einstein)
.vote `should be` GRANTED
}
@Test
fun `other user can be view the article list`(): Unit = listOf(ArticleVoter(mockk())).run {
val article = getArticle(tesla)
val article2 = getArticle(tesla)
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`() {
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`() {
val article = getArticle(tesla)
val article2 = getArticle(tesla).copy(draft = true)
ArticleVoter(getRepo(article))
.canView(listOf(article, article2), einstein)
.vote `should be` DENIED
}
@Test
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`() {
val article = getArticle(tesla)
ArticleVoter(getRepo(article))
.canDelete(article, tesla)
.vote `should be` GRANTED
}
@Test
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`() {
val article = getArticle(tesla)
ArticleVoter(getRepo(article))
.canUpsert(article, tesla)
.vote `should be` GRANTED
}
@Test
fun `can not create article if not logged`() {
val article = getArticle(tesla)
ArticleVoter(getRepo(article))
.canUpsert(article, null)
.code `should be` "article.create.notConnected"
}
@Test
fun `can update article if yours`() {
val article = getArticle(tesla)
ArticleVoter(getRepo(article))
.canUpsert(article, tesla)
.vote `should be` GRANTED
}
@Test
fun `can not update article if not yours`() {
val article = getArticle(tesla)
ArticleVoter(getRepo(article))
.canUpsert(article, einstein)
.code `should be` "article.update.notYours"
}
private fun getArticle(createdBy: CitizenCart = tesla) = ArticleForView(
id = UUID.randomUUID(),
title = "Hello world",
content = "Super",
description = "I Rocks",
createdBy = createdBy,
opinions = mapOf(),
versionId = UUID.randomUUID(),
versionNumber = 1
)
}

View File

@@ -0,0 +1,105 @@
package unit.voter
import fr.dcproject.component.citizen.CitizenBasic
import fr.dcproject.component.citizen.CitizenI
import fr.dcproject.component.citizen.CitizenVoter
import fr.dcproject.entity.User
import fr.dcproject.entity.UserI
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
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.parallel.Execution
import org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Execution(CONCURRENT)
@Tag("voter")
internal class CitizenVoterTest {
private val tesla = CitizenBasic(
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 = CitizenBasic(
user = User(
username = "albert-einstein",
roles = listOf(UserI.Roles.ROLE_USER)
),
birthday = DateTime.now(),
email = "einstein@best.com",
name = CitizenI.Name("Albert", "Einstein")
)
private val curie = CitizenBasic(
user = User(
username = "marie-curie",
roles = listOf(UserI.Roles.ROLE_USER)
),
birthday = DateTime.now(),
email = "curie@best.com",
name = CitizenI.Name("Marie", "Curie"),
deletedAt = DateTime.now()
)
init {
mockkStatic("fr.dcproject.ApplicationContextKt")
}
@Test
fun `can be view the citizen`() {
CitizenVoter()
.canView(subject = einstein, connectedCitizen = tesla)
.vote `should be` GRANTED
}
@Test
fun `can be view the citizen list`() {
CitizenVoter()
.canView(subjects = listOf(tesla, einstein), connectedCitizen = einstein)
.vote `should be` GRANTED
}
@Test
fun `can not view deleted citizen`() {
CitizenVoter()
.canView(subject = curie, connectedCitizen = tesla)
.vote `should be` DENIED
}
@Test
fun `can be update itself`() {
CitizenVoter()
.canUpdate(subject = einstein, connectedCitizen = einstein)
.vote `should be` GRANTED
}
@Test
fun `can not be update other citizen`() {
CitizenVoter()
.canUpdate(subject = tesla, connectedCitizen = einstein)
.vote `should be` DENIED
}
@Test
fun `can be change password of itself`() {
CitizenVoter()
.canChangePassword(subject = einstein, connectedCitizen = einstein)
.vote `should be` GRANTED
}
@Test
fun `can not be change password of other citizen`() {
CitizenVoter()
.canChangePassword(subject = tesla, connectedCitizen = einstein)
.vote `should be` DENIED
}
}

View File

@@ -0,0 +1,168 @@
package unit.voter
import fr.dcproject.component.article.ArticleForView
import fr.dcproject.component.article.ArticleRef
import fr.dcproject.component.citizen.Citizen
import fr.dcproject.component.citizen.CitizenCart
import fr.dcproject.component.citizen.CitizenI
import fr.dcproject.component.comment.generic.CommentForUpdate
import fr.dcproject.component.comment.generic.CommentForView
import fr.dcproject.component.comment.generic.CommentVoter
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.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.Tag
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.parallel.Execution
import org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT
import java.util.*
import fr.dcproject.component.article.ArticleRepository as ArticleRepo
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Execution(CONCURRENT)
@Tag("voter")
internal class CommentVoterTest {
private val tesla = Citizen(
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(
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")
)
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 = einstein2,
description = "blablabla",
title = "Super article"
)
private val comment1 = CommentForView(
content = "Hello",
createdBy = tesla,
target = article1
)
private val commentForUpdate = CommentForUpdate(
content = "Hello",
createdBy = tesla,
target = article1
)
private val comment2 = CommentForView(
content = "Hello2",
createdBy = einstein,
target = article1
)
private val commentTargetDeleted = CommentForView(
content = "Hello",
createdBy = tesla,
target = ArticleForView(
content = "Hi",
createdBy = einstein2,
description = "blablabla",
title = "Super article",
workgroup = null
).copy(deletedAt = DateTime.now())
)
private val commentTargetNoUser = CommentForView(
content = "Hello",
createdBy = tesla,
target = ArticleRef()
)
private val repoArticle1 = mockk<ArticleRepo> {
every { findVersionsByVersionId(1, 1, any()) } returns Paginated(listOf(article1), 0, 1, 1)
}
init {
mockkStatic("fr.dcproject.ApplicationContextKt")
}
@Test
fun `can be view the comment`() {
CommentVoter()
.canView(comment1, tesla)
.vote `should be` GRANTED
}
@Test
fun `can be view the comment list`() {
CommentVoter()
.canView(listOf(comment1, comment2), einstein)
.vote `should be` GRANTED
}
@Test
fun `can be update your comment`() {
CommentVoter()
.canUpdate(comment1, tesla)
.vote `should be` GRANTED
}
@Test
fun `can not be update other comment`() {
CommentVoter()
.canUpdate(comment1, einstein)
.vote `should be` DENIED
}
@Test
fun `can be create a comment`() {
CommentVoter()
.canCreate(comment1, tesla)
.vote `should be` GRANTED
}
@Test
fun `can not be create a comment if target is deleted`() {
CommentVoter()
.canCreate(commentTargetDeleted, tesla)
.vote `should be` DENIED
}
@Test
fun `can not be create a comment with other creator`() {
CommentVoter()
.canCreate(comment1, einstein)
.vote `should be` DENIED
}
@Test
fun `can not be create a comment if not connected`() {
CommentVoter()
.canCreate(comment1, null)
.vote `should be` DENIED
}
}

View File

@@ -0,0 +1,196 @@
package unit.voter
import fr.dcproject.citizenOrNull
import fr.dcproject.component.article.ArticleForView
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.entity.User
import fr.dcproject.entity.UserI
import fr.dcproject.security.voter.FollowVoter
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.*
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.Tag
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.parallel.Execution
import org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT
import java.util.*
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Execution(CONCURRENT)
@Tag("voter")
internal class FollowVoterTest {
private val tesla = CitizenBasic(
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 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)
),
birthday = DateTime.now(),
email = "einstein@best.com",
name = CitizenI.Name("Albert", "Einstein"),
followAnonymous = true
)
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 = einstein2,
description = "blablabla",
title = "Super article"
)
private val follow1 = Follow(
createdBy = tesla,
target = article1
)
private val followAnon = Follow(
createdBy = einstein,
target = article1
)
init {
mockkStatic("fr.dcproject.ApplicationContextKt")
}
@Test
fun `support follow`(): Unit = FollowVoter().run {
val p = object : ActionI {}
mockk<ApplicationCall> {
every { citizenOrNull } returns tesla2
}.let {
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 { citizenOrNull } returns tesla2
}.let {
can(FollowVoter.Action.VIEW, it, follow1) `should be` true
}
}
@Test
fun `can be view the follow list`(): Unit = listOf(FollowVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns tesla2
}.let {
canAll(FollowVoter.Action.VIEW, it, listOf(follow1)) `should be` true
}
}
@Test
fun `can be view your anonymous follow`(): Unit = listOf(FollowVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns einstein3
}.let {
can(FollowVoter.Action.VIEW, it, followAnon) `should be` true
}
}
@Test
fun `can not be view the anonymous follow of other`(): Unit = listOf(FollowVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns tesla2
}.let {
can(FollowVoter.Action.VIEW, it, followAnon) `should be` false
}
}
@Test
fun `can be follow article`(): Unit = listOf(FollowVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns tesla2
}.let {
can(FollowVoter.Action.CREATE, it, follow1) `should be` true
}
}
@Test
fun `can not be follow article if not connected`(): Unit = listOf(FollowVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns null
}.let {
can(FollowVoter.Action.CREATE, it, follow1) `should be` false
}
}
@Test
fun `can be unfollow article`(): Unit = listOf(FollowVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns tesla2
}.let {
can(FollowVoter.Action.DELETE, it, follow1) `should be` true
}
}
@Test
fun `can not be unfollow article if not connected`(): Unit = listOf(FollowVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns null
}.let {
can(FollowVoter.Action.DELETE, it, follow1) `should be` false
}
}
}

View File

@@ -0,0 +1,99 @@
package unit.voter
import fr.dcproject.component.article.ArticleForView
import fr.dcproject.component.citizen.CitizenBasic
import fr.dcproject.component.citizen.CitizenCart
import fr.dcproject.component.citizen.CitizenI
import fr.dcproject.entity.OpinionChoice
import fr.dcproject.entity.User
import fr.dcproject.entity.UserI
import fr.dcproject.security.voter.OpinionChoiceVoter
import fr.dcproject.user
import fr.ktorVoter.ActionI
import fr.ktorVoter.Vote
import fr.ktorVoter.can
import fr.ktorVoter.canAll
import io.ktor.application.*
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.Tag
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.parallel.Execution
import org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT
import java.util.*
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Execution(CONCURRENT)
@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)
),
birthday = DateTime.now(),
email = "tesla@best.com",
name = CitizenI.Name("Nicolas", "Tesla"),
followAnonymous = false
)
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 = tesla2,
description = "blablabla",
title = "Super article"
)
private val choice1 = OpinionChoice(
name = "Opinion1",
target = listOf()
)
init {
mockkStatic("fr.dcproject.ApplicationContextKt")
}
@Test
fun `support opinion choice`(): Unit = OpinionChoiceVoter().run {
val p = object : ActionI {}
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
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
}
}
@Test
fun `can be view the opinion choice`(): Unit = listOf(OpinionChoiceVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
can(OpinionChoiceVoter.Action.VIEW, it, choice1) `should be` true
}
}
@Test
fun `can be view the opinion choice list`(): Unit = listOf(OpinionChoiceVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
canAll(OpinionChoiceVoter.Action.VIEW, it, listOf(choice1)) `should be` true
}
}
}

View File

@@ -0,0 +1,171 @@
package unit.voter
import fr.dcproject.component.article.ArticleForView
import fr.dcproject.component.citizen.CitizenBasic
import fr.dcproject.component.citizen.CitizenCart
import fr.dcproject.component.citizen.CitizenI
import fr.dcproject.entity.Opinion
import fr.dcproject.entity.OpinionChoice
import fr.dcproject.entity.User
import fr.dcproject.entity.UserI
import fr.dcproject.security.voter.OpinionVoter
import fr.dcproject.user
import fr.dcproject.voter.NoSubjectDefinedException
import fr.ktorVoter.*
import io.ktor.application.*
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.Tag
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.parallel.Execution
import org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT
import java.util.*
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Execution(CONCURRENT)
@Tag("voter")
internal class OpinionVoterTest {
private val tesla = CitizenBasic(
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)
),
birthday = DateTime.now(),
email = "einstein@best.com",
name = CitizenI.Name("Albert", "Einstein"),
followAnonymous = true
)
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 = einstein2,
description = "blablabla",
title = "Super article"
)
private val opinion1 = Opinion(
createdBy = tesla,
target = article1,
choice = OpinionChoice(
name = "Opinion1",
target = listOf("article")
)
)
init {
mockkStatic("fr.dcproject.ApplicationContextKt")
}
@Test
fun `support opinion`(): Unit = OpinionVoter().run {
val p = object : ActionI {}
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
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
}
}
@Test
fun `can be view the opinion`(): Unit = listOf(OpinionVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
can(OpinionVoter.Action.VIEW, it, opinion1) `should be` true
}
}
@Test
fun `can be not view the opinion if is null`(): Unit = listOf(OpinionVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
assertThrows<NoSubjectDefinedException> {
assertCan(OpinionVoter.Action.VIEW, it, null)
}
}
}
@Test
fun `can be view the opinion list`(): Unit = listOf(OpinionVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
canAll(OpinionVoter.Action.VIEW, it, listOf(opinion1)) `should be` true
}
}
@Test
fun `can be opinion an article`(): Unit = listOf(OpinionVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
can(OpinionVoter.Action.CREATE, it, opinion1) `should be` true
}
}
@Test
fun `can not be opinion if not connected`() = listOf(OpinionVoter()).run {
mockk<ApplicationCall> {
every { user } returns null
}.let {
can(OpinionVoter.Action.CREATE, it, opinion1) `should be` false
}
}
@Test
fun `can be remove opinion`(): Unit = listOf(OpinionVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
can(OpinionVoter.Action.DELETE, it, opinion1) `should be` true
}
}
@Test
fun `can not be remove opinion if not connected`(): Unit = listOf(OpinionVoter()).run {
mockk<ApplicationCall> {
every { user } returns null
}.let {
can(OpinionVoter.Action.DELETE, it, opinion1) `should be` false
}
}
@Test
fun `can not be remove opinion of other user`(): Unit = listOf(OpinionVoter()).run {
mockk<ApplicationCall> {
every { user } returns einstein.user
}.let {
can(OpinionVoter.Action.DELETE, it, opinion1) `should be` false
}
}
}

View File

@@ -0,0 +1,220 @@
package unit.voter
import fr.dcproject.citizenOrNull
import fr.dcproject.component.article.ArticleForView
import fr.dcproject.component.article.ArticleRef
import fr.dcproject.component.citizen.Citizen
import fr.dcproject.component.citizen.CitizenBasic
import fr.dcproject.component.citizen.CitizenCart
import fr.dcproject.component.citizen.CitizenI
import fr.dcproject.entity.User
import fr.dcproject.entity.UserI
import fr.dcproject.entity.VoteForUpdate
import fr.dcproject.security.voter.VoteVoter
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.*
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.Tag
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.parallel.Execution
import org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT
import java.util.*
import fr.dcproject.entity.Vote as VoteEntity
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Execution(CONCURRENT)
@Tag("voter")
internal class VoteVoterTest {
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)
),
birthday = DateTime.now(),
email = "tesla@best.com",
name = CitizenI.Name("Nicolas", "Tesla"),
followAnonymous = false
)
private val einstein = 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 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 = 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 = VoteForUpdate(
createdBy = tesla,
target = ArticleForView(
content = "Hi",
createdBy = einstein2,
description = "blablabla",
title = "Super article"
).copy(deletedAt = DateTime.now()),
note = 1
)
private val voteWithoutTargetUser = VoteForUpdate(
createdBy = tesla,
target = ArticleRef(),
note = 1
)
init {
mockkStatic("fr.dcproject.ApplicationContextKt")
}
@Test
fun `support vote`(): Unit = VoteVoter().run {
val p = object : ActionI {}
mockk<ApplicationCall> {
every { citizenOrNull } returns tesla
}.let {
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 { citizenOrNull } returns tesla
}.let {
can(VoteVoter.Action.VIEW, it, vote1) `should be` true
}
}
@Test
fun `can not be view vote of other`(): Unit = listOf(VoteVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns einstein
}.let {
can(VoteVoter.Action.VIEW, it, vote1) `should be` false
}
}
@Test
fun `can be not view the vote if is null`(): Unit = listOf(VoteVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns tesla
}.let {
assertThrows<NoSubjectDefinedException> {
can(VoteVoter.Action.VIEW, it, null)
}
}
}
@Test
fun `can be view your votes list`(): Unit = listOf(VoteVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns tesla
}.let {
canAll(VoteVoter.Action.VIEW, it, listOf(vote1)) `should be` true
}
}
@Test
fun `can be vote an article`() {
listOf(VoteVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns tesla
}.let {
can(VoteVoter.Action.CREATE, it, voteForUpdate) `should be` true
}
}
}
@Test
fun `can not be vote if not connected`(): Unit = listOf(VoteVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns null
}.let {
can(VoteVoter.Action.CREATE, it, voteForUpdate) `should be` false
}
}
@Test
fun `can not be vote an article if article is deleted`(): Unit = listOf(VoteVoter()).run {
mockk<ApplicationCall> {
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()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns tesla
}.let {
assertThrows<NoSubjectDefinedException> {
can(VoteVoter.Action.CREATE, it, voteWithoutTargetUser)
}
}
}
@Test
fun `can not be comment an article if article is deleted`(): Unit = listOf(VoteVoter()).run {
mockk<ApplicationCall> {
every { citizenOrNull } returns tesla
}.let {
can(VoteVoter.Action.CREATE, it, voteOnDeleted) `should be` false
}
}
}

View File

@@ -0,0 +1,231 @@
package unit.voter
import fr.dcproject.component.article.ArticleForView
import fr.dcproject.component.citizen.CitizenBasic
import fr.dcproject.component.citizen.CitizenCart
import fr.dcproject.component.citizen.CitizenI
import fr.dcproject.entity.User
import fr.dcproject.entity.UserI
import fr.dcproject.entity.WorkgroupRef
import fr.dcproject.entity.WorkgroupWithMembersI
import fr.dcproject.security.voter.WorkgroupVoter
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.*
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.*
import org.junit.jupiter.api.parallel.Execution
import org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT
import java.util.*
import fr.dcproject.entity.Workgroup as WorkgroupEntity
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Execution(CONCURRENT)
@Tag("voter")
internal class WorkgroupVoterTest {
private val tesla = CitizenBasic(
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)
),
birthday = DateTime.now(),
email = "einstein@best.com",
name = CitizenI.Name("Albert", "Einstein"),
followAnonymous = true
)
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 = einstein2,
description = "blablabla",
title = "Super article"
)
private val workgroupPublic = WorkgroupEntity(
createdBy = tesla,
description = "Super desc",
name = "super name",
anonymous = false,
members = listOf(WorkgroupWithMembersI.Member(tesla, listOf(WorkgroupWithMembersI.Member.Role.MASTER)))
)
private val workgroupAnon = WorkgroupEntity(
createdBy = tesla,
description = "Super desc",
name = "super name",
members = listOf(WorkgroupWithMembersI.Member(tesla, listOf(WorkgroupWithMembersI.Member.Role.MASTER))),
anonymous = true
)
private val workgroupref = WorkgroupRef()
init {
mockkStatic("fr.dcproject.ApplicationContextKt")
}
@Test
fun `support workgroup`(): Unit = WorkgroupVoter().run {
val p = object : ActionI {}
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
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
}
}
@Test
fun `can be view your workgroup`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
can(WorkgroupVoter.Action.VIEW, it, workgroupPublic) `should be` true
}
}
@Test
fun `can be view your workgroup if is not public`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
can(WorkgroupVoter.Action.VIEW, it, workgroupAnon) `should be` true
}
}
@Test
fun `can be view workgroup of other if is public`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns einstein.user
}.let {
can(WorkgroupVoter.Action.VIEW, it, workgroupPublic) `should be` true
}
}
@Test
fun `can not be view workgroup of other if is not public`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns einstein.user
}.let {
can(WorkgroupVoter.Action.VIEW, it, workgroupAnon) `should be` false
}
}
@Test
fun `can be not view the workgroup if is null`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
assertThrows<NoSubjectDefinedException> {
can(WorkgroupVoter.Action.VIEW, it, null)
}
}
}
@Test
fun `can be view your workgroup list`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
listOf(workgroupPublic).map { workgroup ->
can(WorkgroupVoter.Action.VIEW, it, workgroup)
}.all { it } `should be` true
}
}
@Test
fun `can be create workgroup`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
can(WorkgroupVoter.Action.CREATE, it, workgroupPublic) `should be` true
}
}
@Test
fun `can not be create workgroup if not connected`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns null
}.let {
can(WorkgroupVoter.Action.CREATE, it, workgroupPublic) `should be` false
}
}
@Test
fun `can be delete workgroup if owner`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
can(WorkgroupVoter.Action.DELETE, it, workgroupPublic) `should be` true
}
}
@Test
fun `can not be delete workgroup if not owner`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns einstein.user
}.let {
can(WorkgroupVoter.Action.DELETE, it, workgroupPublic) `should be` false
}
}
@Test
fun `can be update workgroup if owner`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
can(WorkgroupVoter.Action.UPDATE, it, workgroupPublic) `should be` true
}
}
@Test
fun `can not be update workgroup if not owner`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns einstein.user
}.let {
can(WorkgroupVoter.Action.UPDATE, it, workgroupPublic) `should be` false
}
}
@Test
fun `can not be update workgroup if workgroup has no user`() {
Assertions.assertThrows(VoterException::class.java) {
listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> {
every { user } returns tesla.user
}.let {
can(WorkgroupVoter.Action.UPDATE, it, workgroupref)
}
}
}
}
}