Init Integration test without cucumber

This commit is contained in:
2021-02-09 02:51:23 +01:00
parent dcf35eaccd
commit edf0c00cf1
6 changed files with 200 additions and 3 deletions

View File

@@ -0,0 +1,119 @@
package integration
import com.rabbitmq.client.Channel
import com.rabbitmq.client.ConnectionFactory
import fr.dcproject.application.Configuration
import fr.dcproject.application.Env.TEST
import fr.dcproject.application.module
import fr.postgresjson.connexion.Connection
import fr.postgresjson.migration.Migrations
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpMethod
import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.server.testing.TestApplicationCall
import io.ktor.server.testing.TestApplicationEngine
import io.ktor.server.testing.TestApplicationRequest
import io.ktor.server.testing.TestApplicationResponse
import io.ktor.server.testing.createTestEnvironment
import io.ktor.server.testing.setBody
import io.ktor.util.KtorExperimentalAPI
import io.lettuce.core.RedisClient
import io.lettuce.core.api.sync.RedisCommands
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.amshove.kluent.`should be`
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.BeforeEach
import org.koin.test.KoinTest
import org.koin.test.get
@ExperimentalCoroutinesApi
@KtorExperimentalAPI
@KtorExperimentalLocationsAPI
abstract class BaseTest : KoinTest {
companion object {
private var init = false
private val config = Configuration("application-test.conf")
private val redis: RedisCommands<String, String> = RedisClient.create(config.redis).connect().sync()
private val rabbit: Channel = ConnectionFactory()
.apply { setUri(config.rabbitmq) }
.newConnection()
.createChannel()
private val engine = TestApplicationEngine(createTestEnvironment())
}
protected fun <R> withIntegrationApplication(
test: TestApplicationEngine.() -> R
): R {
return engine.test()
}
public fun TestApplicationEngine.handleGetRequest(uri: String? = null, body: TestApplicationRequest.() -> String): TestApplicationCall {
val setupOveride: TestApplicationRequest.() -> Unit = {
method = HttpMethod.Get
if (uri != null) {
this.uri = uri
}
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
setBody(body().trimIndent())
}
return handleRequest(true, setupOveride)
}
public fun TestApplicationEngine.handlePostRequest(uri: String? = null, body: TestApplicationRequest.() -> String): TestApplicationCall {
val setupOveride: TestApplicationRequest.() -> Unit = {
method = HttpMethod.Post
if (uri != null) {
this.uri = uri
}
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
setBody(body().trimIndent())
}
return handleRequest(true, setupOveride)
}
@BeforeAll
fun before() {
if (init == false) {
engine.start()
engine.application.module(TEST)
init = true
get<Migrations>().run {
forceAllDown()
run()
}
get<Connection>()
.sendQuery("start transaction;", listOf())
}
}
@BeforeEach
fun beforeEach() {
redis.flushall()
/* Purge rabbit notification queues */
rabbit.run {
queuePurge("push")
queuePurge("email")
}
get<Connection>()
.sendQuery("savepoint test_begin;", listOf())
}
@AfterEach
fun afterEach() {
get<Connection>()
.sendQuery("rollback to savepoint test_begin;", listOf())
}
}
fun TestApplicationCall.`should be respond`(status: HttpStatusCode? = null, block: TestApplicationResponse.() -> Unit) {
if (status != null) {
response.status().`should be`(status)
}
block(response)
}

View File

@@ -0,0 +1,40 @@
package integration
import integration.prerequisite.CitizenPrerequisite
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`
import org.amshove.kluent.`should contain`
import org.amshove.kluent.`should not be null`
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Tags
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
@ExperimentalCoroutinesApi
@KtorExperimentalLocationsAPI
@KtorExperimentalAPI
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Tags(Tag("integration"))
class LoginTest : BaseTest() {
@Test
fun `I can login`() {
withIntegrationApplication {
CitizenPrerequisite().createCitizen("Niels", "Bohr")
handlePostRequest("/login") {
"""
{
"username": "niels-bohr",
"password": "azerty"
}
"""
}.`should be respond` (HttpStatusCode.OK) {
content
.`should not be null`()
.`should contain`("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.")
}
}
}
}

View File

@@ -0,0 +1,36 @@
package integration.prerequisite
import fr.dcproject.component.auth.UserForCreate
import fr.dcproject.component.citizen.Citizen
import fr.dcproject.component.citizen.CitizenForCreate
import fr.dcproject.component.citizen.CitizenI
import fr.dcproject.component.citizen.CitizenRepository
import org.joda.time.DateTime
import org.koin.core.KoinComponent
import org.koin.core.get
import java.util.UUID
class CitizenPrerequisite : KoinComponent {
fun createCitizen(
firstName: String,
lastName: String,
email: String = ("$firstName-$lastName".toLowerCase()) + "@dc-project.fr",
id: UUID = UUID.randomUUID()
): Citizen? {
val user = UserForCreate(
id = id,
username = "$firstName-$lastName".toLowerCase(),
password = "azerty",
)
val citizen = CitizenForCreate(
id = id,
name = CitizenI.Name(firstName, lastName),
email = email,
birthday = DateTime.now(),
user = user
)
return get<CitizenRepository>().insertWithUser(citizen)
}
}