Add Integration test for Register

This commit is contained in:
2021-02-09 20:56:27 +01:00
parent edf0c00cf1
commit 55bfbb619d
8 changed files with 227 additions and 34 deletions

View File

@@ -0,0 +1,23 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Functional Tests (offline)" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
<useClassPathOnly />
<option name="PACKAGE_NAME" value="fr.dcproject" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="tags" />
<option name="VM_PARAMETERS" value="-ea -Djdk.attach.allowAttachSelf=true" />
<option name="PARAMETERS" value="" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="wholeProject" />
</option>
<envs>
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
</envs>
<dir value="$PROJECT_DIR$" />
<tag value="functional&amp;!online" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@@ -0,0 +1,28 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Integration Tests" type="JUnit" factoryName="JUnit" singleton="false" show_console_on_std_err="true">
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
<useClassPathOnly />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="corretto-11" />
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="pattern" />
<option name="VM_PARAMETERS" value="-ea -Djdk.attach.allowAttachSelf=true" />
<option name="PARAMETERS" value="" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="wholeProject" />
</option>
<envs>
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
</envs>
<dir value="$PROJECT_DIR$" />
<patterns>
<pattern testClass="integration..*" />
</patterns>
<tag value="!functional" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@@ -0,0 +1,30 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Unit, functional and integration tests" type="JUnit" factoryName="JUnit" singleton="false" show_console_on_std_err="true">
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
<useClassPathOnly />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="corretto-11" />
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="pattern" />
<option name="VM_PARAMETERS" value="-ea -Djdk.attach.allowAttachSelf=true" />
<option name="PARAMETERS" value="" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="wholeProject" />
</option>
<envs>
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
</envs>
<dir value="$PROJECT_DIR$" />
<patterns>
<pattern testClass="unit..*" />
<pattern testClass="functional..*" />
<pattern testClass="integration..*" />
</patterns>
<tag value="!functional" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@@ -0,0 +1,29 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Unit and functional tests" type="JUnit" factoryName="JUnit" singleton="false" show_console_on_std_err="true">
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
<useClassPathOnly />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="corretto-11" />
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="pattern" />
<option name="VM_PARAMETERS" value="-ea -Djdk.attach.allowAttachSelf=true" />
<option name="PARAMETERS" value="" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="wholeProject" />
</option>
<envs>
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
</envs>
<dir value="$PROJECT_DIR$" />
<patterns>
<pattern testClass="unit..*" />
<pattern testClass="functional..*" />
</patterns>
<tag value="!functional" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@@ -50,30 +50,36 @@ abstract class BaseTest : KoinTest {
return engine.test() return engine.test()
} }
public fun TestApplicationEngine.handleGetRequest(uri: String? = null, body: TestApplicationRequest.() -> String): TestApplicationCall { public fun TestApplicationEngine.`I send a GET request`(uri: String? = null, setup: (TestApplicationRequest.() -> Unit)? = null): TestApplicationCall {
val setupOveride: TestApplicationRequest.() -> Unit = { val setupOveride: TestApplicationRequest.() -> Unit = {
method = HttpMethod.Get method = HttpMethod.Get
if (uri != null) { if (uri != null) {
this.uri = uri this.uri = uri
} }
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString()) addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
setBody(body().trimIndent()) setup?.let { it() }
} }
return handleRequest(true, setupOveride) return handleRequest(true, setupOveride)
} }
public fun TestApplicationEngine.handlePostRequest(uri: String? = null, body: TestApplicationRequest.() -> String): TestApplicationCall { public fun TestApplicationEngine.`I send a POST request`(uri: String? = null, setup: (TestApplicationRequest.() -> String?)? = null): TestApplicationCall {
val setupOveride: TestApplicationRequest.() -> Unit = { val setupOveride: TestApplicationRequest.() -> Unit = {
method = HttpMethod.Post method = HttpMethod.Post
if (uri != null) { if (uri != null) {
this.uri = uri this.uri = uri
} }
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString()) addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
setBody(body().trimIndent()) setup?.let { it() }?.let {
setBody(it.trimIndent())
}
} }
return handleRequest(true, setupOveride) return handleRequest(true, setupOveride)
} }
fun TestApplicationRequest.`with body`(body: String) {
setBody(body.trimIndent())
}
@BeforeAll @BeforeAll
fun before() { fun before() {
if (init == false) { if (init == false) {
@@ -110,10 +116,11 @@ abstract class BaseTest : KoinTest {
} }
fun TestApplicationCall.`should be respond`(status: HttpStatusCode? = null, block: TestApplicationResponse.() -> Unit) { fun TestApplicationCall.`Then the response should be`(status: HttpStatusCode? = null, block: TestApplicationResponse.() -> Unit): TestApplicationCall {
if (status != null) { if (status != null) {
response.status().`should be`(status) response.status().`should be`(status)
} }
block(response) block(response)
return this
} }

View File

@@ -1,11 +1,12 @@
package integration package integration.auth
import integration.prerequisite.CitizenPrerequisite import integration.BaseTest
import integration.`Then the response should be`
import integration.prerequisite.`Given I have citizen`
import io.ktor.http.HttpStatusCode import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.util.KtorExperimentalAPI import io.ktor.util.KtorExperimentalAPI
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.amshove.kluent.`should be`
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.jupiter.api.Tag import org.junit.jupiter.api.Tag
@@ -17,20 +18,20 @@ import org.junit.jupiter.api.TestInstance
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@KtorExperimentalAPI @KtorExperimentalAPI
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Tags(Tag("integration")) @Tags(Tag("integration"), Tag("auth"))
class LoginTest : BaseTest() { class LoginTest : BaseTest() {
@Test @Test
fun `I can login`() { fun `I can login with username and password`() {
withIntegrationApplication { withIntegrationApplication {
CitizenPrerequisite().createCitizen("Niels", "Bohr") `Given I have citizen`("Niels", "Bohr")
handlePostRequest("/login") { `I send a POST request`("/login") {
""" """
{ {
"username": "niels-bohr", "username": "niels-bohr",
"password": "azerty" "password": "azerty"
} }
""" """
}.`should be respond` (HttpStatusCode.OK) { }.`Then the response should be` (HttpStatusCode.OK) {
content content
.`should not be null`() .`should not be null`()
.`should contain`("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.") .`should contain`("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.")

View File

@@ -0,0 +1,68 @@
package integration.auth
import integration.BaseTest
import integration.`Then the response should be`
import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.server.testing.setBody
import io.ktor.util.KtorExperimentalAPI
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.amshove.kluent.`should be null`
import org.amshove.kluent.`should contain`
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.Tags
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
@ExperimentalCoroutinesApi
@KtorExperimentalLocationsAPI
@KtorExperimentalAPI
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Tags(Tag("integration"), Tag("auth"))
class RegisterTest : BaseTest() {
@Test
@Category(RegisterTest::class)
fun `I can register`() {
withIntegrationApplication {
`I send a POST request`("/register") {
"""
{
"name": {"first_name":"George", "last_name":"MICHEL"},
"birthday": "2001-01-01",
"user":{
"username": "george-junior",
"password": "azerty"
},
"email": "george-junior@gmail.com"
}
"""
}.`Then the response should be` (HttpStatusCode.OK) {
content
.`should not be null`()
.`should contain`("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.")
}
}
}
@Test
fun `I cannot register if no username was sent`() {
withIntegrationApplication {
`I send a POST request`("/register") {
"""
{
"name": {"first_name":"George2", "last_name":"MICHEL2"},
"birthday": "2001-01-01",
"user":{
"username": "",
"password": ""
}
}
"""
}.`Then the response should be` (HttpStatusCode.BadRequest) {
content.`should be null`()
}
}
}
}

View File

@@ -1,36 +1,43 @@
package integration.prerequisite package integration.prerequisite
import com.auth0.jwt.JWT
import fr.dcproject.component.auth.UserForCreate import fr.dcproject.component.auth.UserForCreate
import fr.dcproject.component.auth.jwt.JwtConfig
import fr.dcproject.component.citizen.Citizen import fr.dcproject.component.citizen.Citizen
import fr.dcproject.component.citizen.CitizenForCreate import fr.dcproject.component.citizen.CitizenForCreate
import fr.dcproject.component.citizen.CitizenI import fr.dcproject.component.citizen.CitizenI
import fr.dcproject.component.citizen.CitizenRepository import fr.dcproject.component.citizen.CitizenRepository
import io.ktor.http.HttpHeaders
import io.ktor.server.testing.TestApplicationEngine
import io.ktor.server.testing.TestApplicationRequest
import org.joda.time.DateTime import org.joda.time.DateTime
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
import org.koin.core.context.GlobalContext
import org.koin.core.get import org.koin.core.get
import org.koin.test.get
import steps.KtorServerContext
import java.util.UUID import java.util.UUID
class CitizenPrerequisite : KoinComponent { fun TestApplicationEngine.`Given I have citizen`(
fun createCitizen( firstName: String,
firstName: String, lastName: String,
lastName: String, email: String = ("$firstName-$lastName".toLowerCase()) + "@dc-project.fr",
email: String = ("$firstName-$lastName".toLowerCase()) + "@dc-project.fr", id: UUID = UUID.randomUUID()
id: UUID = UUID.randomUUID() ): Citizen? {
): Citizen? { val repo: CitizenRepository by lazy<CitizenRepository> { GlobalContext.get().koin.get() }
val user = UserForCreate( val user = UserForCreate(
id = id, id = id,
username = "$firstName-$lastName".toLowerCase(), username = "$firstName-$lastName".toLowerCase(),
password = "azerty", password = "azerty",
) )
val citizen = CitizenForCreate( val citizen = CitizenForCreate(
id = id, id = id,
name = CitizenI.Name(firstName, lastName), name = CitizenI.Name(firstName, lastName),
email = email, email = email,
birthday = DateTime.now(), birthday = DateTime.now(),
user = user user = user
) )
return get<CitizenRepository>().insertWithUser(citizen) return repo.insertWithUser(citizen)
}
} }