Add Integration test for article
This commit is contained in:
97
src/test/kotlin/integration/Article routes.kt
Normal file
97
src/test/kotlin/integration/Article routes.kt
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import integration.asserts.`And have property`
|
||||||
|
import integration.asserts.`And the response should not be null`
|
||||||
|
import integration.asserts.`Then the response should be`
|
||||||
|
import integration.asserts.`when`.`When I send a GET request`
|
||||||
|
import integration.asserts.`when`.`When I send a POST request`
|
||||||
|
import integration.asserts.`whish contains`
|
||||||
|
import integration.asserts.and
|
||||||
|
import integration.asserts.given.`Given I have article created by workgroup`
|
||||||
|
import integration.asserts.given.`Given I have article`
|
||||||
|
import integration.asserts.given.`Given I have articles`
|
||||||
|
import integration.asserts.given.`Given I have citizen`
|
||||||
|
import integration.asserts.given.`Given I have workgroup`
|
||||||
|
import integration.asserts.given.`authenticated as`
|
||||||
|
import io.ktor.http.HttpStatusCode.Companion.OK
|
||||||
|
import org.junit.jupiter.api.Tag
|
||||||
|
import org.junit.jupiter.api.Tags
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
@Tags(Tag("integration"), Tag("citizen"))
|
||||||
|
class `Article routes` : BaseTest() {
|
||||||
|
@Test
|
||||||
|
fun `I can get article list`() {
|
||||||
|
withIntegrationApplication {
|
||||||
|
`Given I have articles`(3)
|
||||||
|
`When I send a GET request`("/articles") `Then the response should be` OK and {
|
||||||
|
`And the response should not be null`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `I can get articles filtered by workgroup`() {
|
||||||
|
withIntegrationApplication {
|
||||||
|
`Given I have articles`(3)
|
||||||
|
`Given I have workgroup`(name = "Les papy", id = "2bccd5a7-9082-4b31-88f8-e25d70b22b12")
|
||||||
|
`Given I have article created by workgroup`("2bccd5a7-9082-4b31-88f8-e25d70b22b12")
|
||||||
|
`When I send a GET request`("/articles?workgroup=2bccd5a7-9082-4b31-88f8-e25d70b22b12") `Then the response should be` OK and {
|
||||||
|
`And the response should not be null`
|
||||||
|
`And have property`("$.total") `whish contains` 1
|
||||||
|
`And have property`("$.result[0]workgroup.name") `whish contains` "Les papy"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `I can get versions of article by the id`() {
|
||||||
|
withIntegrationApplication {
|
||||||
|
`Given I have article`(id = "13e6091c-8fed-4600-b079-a97a6b7a9800")
|
||||||
|
`When I send a GET request`("/articles/13e6091c-8fed-4600-b079-a97a6b7a9800/versions") `Then the response should be` OK and {
|
||||||
|
`And the response should not be null`
|
||||||
|
`And have property`("$.total") `whish contains` 1
|
||||||
|
`And have property`("$.result[0].id") `whish contains` "13e6091c-8fed-4600-b079-a97a6b7a9800"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `I can get article by id`() {
|
||||||
|
withIntegrationApplication {
|
||||||
|
`Given I have article`(id = "65cda9f3-8991-4420-8d41-1da9da72c9bb")
|
||||||
|
`When I send a GET request`("/articles/65cda9f3-8991-4420-8d41-1da9da72c9bb") `Then the response should be` OK and {
|
||||||
|
`And the response should not be null`
|
||||||
|
`And have property`("$.id") `whish contains` "65cda9f3-8991-4420-8d41-1da9da72c9bb"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `I can create an article`() {
|
||||||
|
withIntegrationApplication {
|
||||||
|
`Given I have citizen`("John", "Doe")
|
||||||
|
`When I send a POST request`("/articles") {
|
||||||
|
`authenticated as`("John", "Doe")
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
"version_id": "09c418b6-63ba-448b-b38b-502b41cd500e",
|
||||||
|
"title": "title2",
|
||||||
|
"annonymous": false,
|
||||||
|
"content": "content2",
|
||||||
|
"description": "description2",
|
||||||
|
"tags": [
|
||||||
|
"green"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
} `Then the response should be` OK and {
|
||||||
|
`And the response should not be null`
|
||||||
|
`And have property`("$.version_id") `whish contains` "09c418b6-63ba-448b-b38b-502b41cd500e"
|
||||||
|
`And have property`("$.title") `whish contains` "title2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,6 @@ import io.ktor.util.KtorExperimentalAPI
|
|||||||
import io.lettuce.core.RedisClient
|
import io.lettuce.core.RedisClient
|
||||||
import io.lettuce.core.api.sync.RedisCommands
|
import io.lettuce.core.api.sync.RedisCommands
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.isActive
|
|
||||||
import org.junit.jupiter.api.AfterAll
|
import org.junit.jupiter.api.AfterAll
|
||||||
import org.junit.jupiter.api.AfterEach
|
import org.junit.jupiter.api.AfterEach
|
||||||
import org.junit.jupiter.api.BeforeAll
|
import org.junit.jupiter.api.BeforeAll
|
||||||
@@ -22,9 +21,6 @@ import org.junit.jupiter.api.BeforeEach
|
|||||||
import org.koin.test.KoinTest
|
import org.koin.test.KoinTest
|
||||||
import org.koin.test.get
|
import org.koin.test.get
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
|
||||||
@KtorExperimentalAPI
|
|
||||||
@KtorExperimentalLocationsAPI
|
|
||||||
abstract class BaseTest : KoinTest {
|
abstract class BaseTest : KoinTest {
|
||||||
companion object {
|
companion object {
|
||||||
private var init = false
|
private var init = false
|
||||||
@@ -44,6 +40,9 @@ abstract class BaseTest : KoinTest {
|
|||||||
return engine.test()
|
return engine.test()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
@KtorExperimentalAPI
|
||||||
|
@KtorExperimentalLocationsAPI
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
fun before() {
|
fun before() {
|
||||||
engine.start()
|
engine.start()
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package integration
|
package integration
|
||||||
|
|
||||||
import integration.BaseTest
|
|
||||||
import integration.asserts.`And have property`
|
import integration.asserts.`And have property`
|
||||||
import integration.asserts.`And the response should not be null`
|
import integration.asserts.`And the response should not be null`
|
||||||
import integration.asserts.`Then the response should be`
|
import integration.asserts.`Then the response should be`
|
||||||
@@ -13,17 +12,11 @@ import integration.asserts.given.`authenticated as`
|
|||||||
import io.ktor.http.HttpStatusCode.Companion.BadRequest
|
import io.ktor.http.HttpStatusCode.Companion.BadRequest
|
||||||
import io.ktor.http.HttpStatusCode.Companion.Created
|
import io.ktor.http.HttpStatusCode.Companion.Created
|
||||||
import io.ktor.http.HttpStatusCode.Companion.OK
|
import io.ktor.http.HttpStatusCode.Companion.OK
|
||||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
|
||||||
import io.ktor.util.KtorExperimentalAPI
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import org.junit.jupiter.api.Tag
|
import org.junit.jupiter.api.Tag
|
||||||
import org.junit.jupiter.api.Tags
|
import org.junit.jupiter.api.Tags
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
|
||||||
@KtorExperimentalLocationsAPI
|
|
||||||
@KtorExperimentalAPI
|
|
||||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
@Tags(Tag("integration"), Tag("citizen"))
|
@Tags(Tag("integration"), Tag("citizen"))
|
||||||
class `Citizen routes` : BaseTest() {
|
class `Citizen routes` : BaseTest() {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package integration
|
package integration
|
||||||
|
|
||||||
import integration.BaseTest
|
|
||||||
import integration.asserts.`And the response should not be null`
|
import integration.asserts.`And the response should not be null`
|
||||||
import integration.asserts.`Then the response should be`
|
import integration.asserts.`Then the response should be`
|
||||||
import integration.asserts.`and should contains`
|
import integration.asserts.`and should contains`
|
||||||
@@ -9,17 +8,11 @@ import integration.asserts.given.`Given I have citizen`
|
|||||||
import integration.asserts.given.`authenticated as`
|
import integration.asserts.given.`authenticated as`
|
||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.http.HttpStatusCode
|
||||||
import io.ktor.http.HttpStatusCode.Companion.NoContent
|
import io.ktor.http.HttpStatusCode.Companion.NoContent
|
||||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
|
||||||
import io.ktor.util.KtorExperimentalAPI
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import org.junit.jupiter.api.Tag
|
import org.junit.jupiter.api.Tag
|
||||||
import org.junit.jupiter.api.Tags
|
import org.junit.jupiter.api.Tags
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
|
||||||
@KtorExperimentalLocationsAPI
|
|
||||||
@KtorExperimentalAPI
|
|
||||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
@Tags(Tag("integration"), Tag("auth"))
|
@Tags(Tag("integration"), Tag("auth"))
|
||||||
class `Login routes` : BaseTest() {
|
class `Login routes` : BaseTest() {
|
||||||
|
|||||||
@@ -3,21 +3,14 @@ package integration
|
|||||||
import integration.asserts.`Then the response should be`
|
import integration.asserts.`Then the response should be`
|
||||||
import integration.asserts.`when`.`When I send a POST request`
|
import integration.asserts.`when`.`When I send a POST request`
|
||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.http.HttpStatusCode
|
||||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
|
||||||
import io.ktor.util.KtorExperimentalAPI
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import org.amshove.kluent.`should be null`
|
import org.amshove.kluent.`should be null`
|
||||||
import org.amshove.kluent.`should contain`
|
import org.amshove.kluent.`should contain`
|
||||||
import org.amshove.kluent.`should not be null`
|
import org.amshove.kluent.`should not be null`
|
||||||
import org.junit.experimental.categories.Category
|
|
||||||
import org.junit.jupiter.api.Tag
|
import org.junit.jupiter.api.Tag
|
||||||
import org.junit.jupiter.api.Tags
|
import org.junit.jupiter.api.Tags
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
|
||||||
@KtorExperimentalLocationsAPI
|
|
||||||
@KtorExperimentalAPI
|
|
||||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
@Tags(Tag("integration"), Tag("auth"))
|
@Tags(Tag("integration"), Tag("auth"))
|
||||||
class `Register routes` : BaseTest() {
|
class `Register routes` : BaseTest() {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ infix fun TestApplicationResponse.`And have property`(path: String): Pair<JsonPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
infix fun Pair<JsonPath, Any>.`whish contains`(expected: Any): Pair<JsonPath, Any> = this.apply {
|
infix fun Pair<JsonPath, Any>.`whish contains`(expected: Any): Pair<JsonPath, Any> = this.apply {
|
||||||
expected `should be equal to` second
|
second `should be equal to` expected
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TestApplicationResponse.`And the response should contain`(path: String, valueExpected: String) {
|
fun TestApplicationResponse.`And the response should contain`(path: String, valueExpected: String) {
|
||||||
|
|||||||
76
src/test/kotlin/integration/asserts/given/Article.kt
Normal file
76
src/test/kotlin/integration/asserts/given/Article.kt
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
package integration.asserts.given
|
||||||
|
|
||||||
|
import fr.dcproject.common.utils.toUUID
|
||||||
|
import fr.dcproject.component.article.ArticleForUpdate
|
||||||
|
import fr.dcproject.component.article.ArticleRepository
|
||||||
|
import fr.dcproject.component.auth.UserForCreate
|
||||||
|
import fr.dcproject.component.citizen.CitizenForCreate
|
||||||
|
import fr.dcproject.component.citizen.CitizenI
|
||||||
|
import fr.dcproject.component.citizen.CitizenRepository
|
||||||
|
import fr.dcproject.component.workgroup.WorkgroupRef
|
||||||
|
import io.ktor.server.testing.TestApplicationEngine
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
import org.koin.core.context.GlobalContext
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
fun TestApplicationEngine.`Given I have article`(
|
||||||
|
id: String? = null,
|
||||||
|
workgroup: WorkgroupRef? = null,
|
||||||
|
createdByUsername: String? = null
|
||||||
|
) {
|
||||||
|
createArticle(id?.toUUID(), workgroup, createdByUsername)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun TestApplicationEngine.`Given I have articles`(
|
||||||
|
numbers: Int,
|
||||||
|
) {
|
||||||
|
repeat(numbers) {
|
||||||
|
createArticle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun TestApplicationEngine.`Given I have article created by workgroup`(
|
||||||
|
workgroupId: String,
|
||||||
|
) {
|
||||||
|
createArticle(workgroup = WorkgroupRef(workgroupId.toUUID()))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createArticle(
|
||||||
|
id: UUID? = null,
|
||||||
|
workgroup: WorkgroupRef? = null,
|
||||||
|
createdByUsername: String? = null
|
||||||
|
) {
|
||||||
|
val username = (createdByUsername ?: "username" + UUID.randomUUID().toString())
|
||||||
|
.toLowerCase().replace(' ', '-')
|
||||||
|
|
||||||
|
val citizenRepository: CitizenRepository by lazy<CitizenRepository> { GlobalContext.get().koin.get() }
|
||||||
|
val articleRepository: ArticleRepository by lazy<ArticleRepository> { GlobalContext.get().koin.get() }
|
||||||
|
|
||||||
|
val createdBy = if (createdByUsername != null) {
|
||||||
|
citizenRepository.findByUsername(username) ?: error("Citizen not exist")
|
||||||
|
} else {
|
||||||
|
val first = "firstName" + UUID.randomUUID().toString()
|
||||||
|
val last = "lastName" + UUID.randomUUID().toString()
|
||||||
|
CitizenForCreate(
|
||||||
|
birthday = DateTime.now(),
|
||||||
|
name = CitizenI.Name(
|
||||||
|
first,
|
||||||
|
last
|
||||||
|
),
|
||||||
|
email = "$first@fakeemail.com",
|
||||||
|
user = UserForCreate(username = username, password = "azerty")
|
||||||
|
).let {
|
||||||
|
citizenRepository.insertWithUser(it) ?: error("Unable to create User")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val article = ArticleForUpdate(
|
||||||
|
id = id ?: UUID.randomUUID(),
|
||||||
|
title = "hello",
|
||||||
|
content = "bla bla bla",
|
||||||
|
description = "A super article",
|
||||||
|
createdBy = createdBy,
|
||||||
|
workgroup = workgroup,
|
||||||
|
versionId = UUID.randomUUID()
|
||||||
|
)
|
||||||
|
articleRepository.upsert(article)
|
||||||
|
}
|
||||||
68
src/test/kotlin/integration/asserts/given/Workgroup.kt
Normal file
68
src/test/kotlin/integration/asserts/given/Workgroup.kt
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package integration.asserts.given
|
||||||
|
|
||||||
|
import fr.dcproject.common.utils.toUUID
|
||||||
|
import fr.dcproject.component.auth.UserForCreate
|
||||||
|
import fr.dcproject.component.citizen.CitizenBasic
|
||||||
|
import fr.dcproject.component.citizen.CitizenForCreate
|
||||||
|
import fr.dcproject.component.citizen.CitizenI
|
||||||
|
import fr.dcproject.component.citizen.CitizenRepository
|
||||||
|
import fr.dcproject.component.workgroup.Workgroup
|
||||||
|
import fr.dcproject.component.workgroup.WorkgroupRepository
|
||||||
|
import fr.dcproject.component.workgroup.WorkgroupWithMembersI.Member
|
||||||
|
import fr.dcproject.component.workgroup.WorkgroupWithMembersI.Member.Role.MASTER
|
||||||
|
import io.ktor.server.testing.TestApplicationEngine
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
import org.koin.core.context.GlobalContext
|
||||||
|
import org.koin.test.get
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
fun TestApplicationEngine.`Given I have workgroup`(
|
||||||
|
id: String? = null,
|
||||||
|
name: String? = null,
|
||||||
|
description: String? = null,
|
||||||
|
anonymous: Boolean? = null,
|
||||||
|
createdByUsername: String? = null
|
||||||
|
) {
|
||||||
|
createWorkgroup(id?.toUUID(), name, description, anonymous, createdByUsername)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createWorkgroup(
|
||||||
|
id: UUID? = null,
|
||||||
|
name: String? = null,
|
||||||
|
description: String? = null,
|
||||||
|
anonymous: Boolean? = null,
|
||||||
|
createdByUsername: String? = null
|
||||||
|
): Workgroup<CitizenBasic> {
|
||||||
|
val username = (createdByUsername ?: "username" + UUID.randomUUID().toString())
|
||||||
|
.toLowerCase().replace(' ', '-')
|
||||||
|
|
||||||
|
val citizenRepository: CitizenRepository by lazy<CitizenRepository> { GlobalContext.get().koin.get() }
|
||||||
|
val workgroupRepository: WorkgroupRepository by lazy<WorkgroupRepository> { GlobalContext.get().koin.get() }
|
||||||
|
|
||||||
|
val creator = citizenRepository.findByUsername(username.toLowerCase().replace(' ', '-'))
|
||||||
|
?: run {
|
||||||
|
val user = UserForCreate(
|
||||||
|
username = username,
|
||||||
|
password = "azerty",
|
||||||
|
)
|
||||||
|
CitizenForCreate(
|
||||||
|
name = CitizenI.Name("Paul", "Langevin"),
|
||||||
|
email = "$username@dc-project.fr",
|
||||||
|
birthday = DateTime.now(),
|
||||||
|
user = user
|
||||||
|
).let {
|
||||||
|
citizenRepository.insertWithUser(it) ?: error("Unable to create User")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val workgroup = Workgroup(
|
||||||
|
id = id ?: UUID.randomUUID(),
|
||||||
|
name = name ?: "Les Incoruptible",
|
||||||
|
description = description ?: "La vie est notre jeux",
|
||||||
|
createdBy = creator,
|
||||||
|
anonymous = (anonymous ?: false) == true,
|
||||||
|
members = listOf(Member(creator, listOf(MASTER)))
|
||||||
|
)
|
||||||
|
|
||||||
|
return workgroupRepository.upsert(workgroup)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user