package integration.routing import be.vandewalleh.auth.SimpleJWT import be.vandewalleh.entities.User import be.vandewalleh.mainModule import be.vandewalleh.module import be.vandewalleh.services.UserService import io.ktor.http.* import io.ktor.server.testing.* import io.mockk.every import io.mockk.mockk import io.mockk.verify import org.amshove.kluent.* import org.json.JSONObject import org.junit.jupiter.api.* import org.kodein.di.Kodein import org.kodein.di.generic.bind import org.kodein.di.generic.instance import org.mindrot.jbcrypt.BCrypt import utils.* @TestInstance(TestInstance.Lifecycle.PER_CLASS) class AuthControllerKtTest { private val userService = mockk() init { val user = User { password = BCrypt.hashpw("password", BCrypt.gensalt()) username = "existing" } user["id"] = 1 every { userService.getFromUsername("existing") } returns user every { userService.userExists(1) } returns true val user2 = User { password = BCrypt.hashpw("right password", BCrypt.gensalt()) username = "wrong" } user["id"] = 2 every { userService.getFromUsername("wrong") } returns user2 every { userService.getFromUsername("notExisting") } returns null } private val kodein = Kodein { import(mainModule, allowOverride = true) bind(overrides = true) with instance(userService) } private val testEngine = TestApplicationEngine().apply { start() application.module(kodein) } @Nested inner class Login { @Test fun `login existing user with valid password`() { val res = testEngine.post("/user/login") { json { it["username"] = "existing" it["password"] = "password" } } verify { userService.getFromUsername("existing") } res.status() `should be equal to` HttpStatusCode.OK val jsonObject = JSONObject(res.content) val hasToken = jsonObject.has("token") hasToken `should be equal to` true jsonObject.keyList() `should be equal to` listOf("token", "refreshToken") val authJwt by kodein.instance(tag = "auth") val token = jsonObject.getString("token") authJwt.verifier.verify(token) val refreshJwt by kodein.instance(tag = "refresh") val refreshToken = jsonObject.getString("refreshToken") refreshJwt.verifier.verify(refreshToken) } @Test fun `login existing user with invalid password`() { val res = testEngine.post("/user/login") { json { it["username"] = "wrong" it["password"] = "not this" } } verify { userService.getFromUsername("wrong") } res.status() `should be equal to` HttpStatusCode.Unauthorized res.content `should strictly be equal to json` """{msg: "Unauthorized"}""" } @Test fun `login not existing user`() { val res = testEngine.post("/user/login") { json { it["username"] = "notExisting" it["password"] = "babababa" } } verify { userService.getFromUsername("notExisting") } res.status() `should be equal to` HttpStatusCode.Unauthorized res.content `should strictly be equal to json` """{msg: "Unauthorized"}""" } @Test fun `login without body`() { val res = testEngine.post("/user/login") { addHeader(HttpHeaders.ContentType, "application/json") } res.status() `should be equal to` HttpStatusCode.BadRequest } } }