diff --git a/.idea/runConfigurations/Functional_Tests__offline_.xml b/.idea/runConfigurations/Functional_Tests__offline_.xml
new file mode 100644
index 0000000..5dae781
--- /dev/null
+++ b/.idea/runConfigurations/Functional_Tests__offline_.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Integration_Tests.xml b/.idea/runConfigurations/Integration_Tests.xml
new file mode 100644
index 0000000..5129d9e
--- /dev/null
+++ b/.idea/runConfigurations/Integration_Tests.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Unit__functional_and_integration_tests.xml b/.idea/runConfigurations/Unit__functional_and_integration_tests.xml
new file mode 100644
index 0000000..45efb47
--- /dev/null
+++ b/.idea/runConfigurations/Unit__functional_and_integration_tests.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Unit_and_functional_tests.xml b/.idea/runConfigurations/Unit_and_functional_tests.xml
new file mode 100644
index 0000000..ed38f6e
--- /dev/null
+++ b/.idea/runConfigurations/Unit_and_functional_tests.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/kotlin/integration/BaseTest.kt b/src/test/kotlin/integration/BaseTest.kt
index ab11272..678c63d 100644
--- a/src/test/kotlin/integration/BaseTest.kt
+++ b/src/test/kotlin/integration/BaseTest.kt
@@ -50,30 +50,36 @@ abstract class BaseTest : KoinTest {
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 = {
method = HttpMethod.Get
if (uri != null) {
this.uri = uri
}
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
- setBody(body().trimIndent())
+ setup?.let { it() }
}
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 = {
method = HttpMethod.Post
if (uri != null) {
this.uri = uri
}
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
- setBody(body().trimIndent())
+ setup?.let { it() }?.let {
+ setBody(it.trimIndent())
+ }
}
return handleRequest(true, setupOveride)
}
+ fun TestApplicationRequest.`with body`(body: String) {
+ setBody(body.trimIndent())
+ }
+
@BeforeAll
fun before() {
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) {
response.status().`should be`(status)
}
block(response)
+ return this
}
\ No newline at end of file
diff --git a/src/test/kotlin/integration/LoginTest.kt b/src/test/kotlin/integration/auth/LoginTest.kt
similarity index 69%
rename from src/test/kotlin/integration/LoginTest.kt
rename to src/test/kotlin/integration/auth/LoginTest.kt
index 687a78c..d68a9c8 100644
--- a/src/test/kotlin/integration/LoginTest.kt
+++ b/src/test/kotlin/integration/auth/LoginTest.kt
@@ -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.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
@@ -17,20 +18,20 @@ import org.junit.jupiter.api.TestInstance
@KtorExperimentalLocationsAPI
@KtorExperimentalAPI
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-@Tags(Tag("integration"))
+@Tags(Tag("integration"), Tag("auth"))
class LoginTest : BaseTest() {
@Test
- fun `I can login`() {
+ fun `I can login with username and password`() {
withIntegrationApplication {
- CitizenPrerequisite().createCitizen("Niels", "Bohr")
- handlePostRequest("/login") {
+ `Given I have citizen`("Niels", "Bohr")
+ `I send a POST request`("/login") {
"""
{
"username": "niels-bohr",
"password": "azerty"
}
"""
- }.`should be respond` (HttpStatusCode.OK) {
+ }.`Then the response should be` (HttpStatusCode.OK) {
content
.`should not be null`()
.`should contain`("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.")
diff --git a/src/test/kotlin/integration/auth/RegisterTest.kt b/src/test/kotlin/integration/auth/RegisterTest.kt
new file mode 100644
index 0000000..75b3f27
--- /dev/null
+++ b/src/test/kotlin/integration/auth/RegisterTest.kt
@@ -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`()
+ }
+ }
+ }
+}
diff --git a/src/test/kotlin/integration/prerequisite/CitizenPrerequisite.kt b/src/test/kotlin/integration/prerequisite/CitizenPrerequisite.kt
index 91156c7..bc30c3e 100644
--- a/src/test/kotlin/integration/prerequisite/CitizenPrerequisite.kt
+++ b/src/test/kotlin/integration/prerequisite/CitizenPrerequisite.kt
@@ -1,36 +1,43 @@
package integration.prerequisite
+import com.auth0.jwt.JWT
import fr.dcproject.component.auth.UserForCreate
+import fr.dcproject.component.auth.jwt.JwtConfig
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 io.ktor.http.HttpHeaders
+import io.ktor.server.testing.TestApplicationEngine
+import io.ktor.server.testing.TestApplicationRequest
import org.joda.time.DateTime
import org.koin.core.KoinComponent
+import org.koin.core.context.GlobalContext
import org.koin.core.get
+import org.koin.test.get
+import steps.KtorServerContext
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? {
+fun TestApplicationEngine.`Given I have citizen`(
+ firstName: String,
+ lastName: String,
+ email: String = ("$firstName-$lastName".toLowerCase()) + "@dc-project.fr",
+ id: UUID = UUID.randomUUID()
+): Citizen? {
+ val repo: CitizenRepository by lazy { GlobalContext.get().koin.get() }
- 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
- )
+ 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().insertWithUser(citizen)
- }
+ return repo.insertWithUser(citizen)
}