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 org.amshove.kluent.* import org.junit.jupiter.api.* import org.kodein.di.Kodein import org.kodein.di.generic.bind import org.kodein.di.generic.instance import utils.* import java.time.LocalDateTime @TestInstance(TestInstance.Lifecycle.PER_CLASS) class UserControllerKtTest { private val userService = mockk() init { // new user every { userService.userExists("new", "new@test.com") } returns false every { userService.createUser("new", "new@test.com", any()) } returns User { this.createdAt = LocalDateTime.now() this.username = "new" this.email = "new@test.com" } // existing user every { userService.userExists("existing", "existing@test.com") } returns true every { userService.createUser("existing", "existing@test.com", any()) } returns null every { userService.getUserId("existing@test.com") } returns 1 every { userService.deleteUser(1) } returns true andThen false // modified user every { userService.userExists("modified", "modified@test.com") } returns true every { userService.userExists( and(not("modified"), not("existing")), and(not("modified@test.com"), not("existing@test.com")) ) } returns false every { userService.userExists(1) } returns true every { userService.createUser("modified", "modified@test.com", any()) } returns null every { userService.getUserId("modified@test.com") } returns 1 every { userService.updateUser(1, "ThisIsMyNewName", "ThisIsMyNewName@mail.com", any()) } returns Unit } 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 CreateUser { @Test fun `create a new user`() { val res = testEngine.post("/user") { json { it["username"] = "new" it["password"] = "test123abc" it["email"] = "new@test.com" } } res.status() `should be equal to` HttpStatusCode.Created res.content `should be equal to json` """{msg:"Created"}""" } @Test fun `create an existing user`() { val res = testEngine.post("/user") { json { it["username"] = "existing" it["email"] = "existing@test.com" it["password"] = "test123abc" } } res.status() `should be equal to` HttpStatusCode.Conflict res.content `should be equal to json` """{msg:"Conflict"}""" } } @Nested inner class DeleteUser { @Test fun `delete an existing user`() { val authJwt by kodein.instance("auth") val token = authJwt.sign(1) val res = testEngine.delete("/user") { addHeader(HttpHeaders.Authorization, "Bearer $token") } res.status() `should be equal to` HttpStatusCode.OK res.content `should be equal to json` """{msg:"OK"}""" // try again val res2 = testEngine.delete("/user") { setToken(token) } res2.status() `should be equal to` HttpStatusCode.NotFound res2.content `should be equal to json` """{msg:"Not Found"}""" } } @Nested inner class ModifyUser { @Test fun `modify a user`() { val authJwt by kodein.instance("auth") val token = authJwt.sign(1) val res = testEngine.put("/user") { setToken(token) json { it["username"] = "ThisIsMyNewName" it["email"] = "ThisIsMyNewName@mail.com" it["password"] = "ThisIsMyCurrentPassword" } } res.status() `should be equal to` HttpStatusCode.OK res.content `should be equal to json` """{msg:"OK"}""" } } }