Add tests for user registration routes
This commit is contained in:
parent
c3a4e94bd4
commit
589bc18069
4 changed files with 116 additions and 31 deletions
|
@ -66,7 +66,7 @@ fun Application.userRoutes(
|
||||||
User(
|
User(
|
||||||
name = request.username,
|
name = request.username,
|
||||||
password = request.password.hash(),
|
password = request.password.hash(),
|
||||||
email = if (request.email.isNullOrBlank()) null else request.email
|
email = if (request.email.isNullOrBlank()) "" else request.email
|
||||||
)
|
)
|
||||||
).asResponse()
|
).asResponse()
|
||||||
)
|
)
|
||||||
|
@ -96,27 +96,6 @@ fun Application.userRoutes(
|
||||||
?: errorResponse(HttpStatusCode.NotFound)
|
?: errorResponse(HttpStatusCode.NotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
post {
|
|
||||||
val request = call.receive<UserRequest>()
|
|
||||||
if (request.username.isNullOrBlank()) {
|
|
||||||
errorResponse(HttpStatusCode.BadRequest, "Username must not be null or blank")
|
|
||||||
return@post
|
|
||||||
}
|
|
||||||
if (request.password.isNullOrBlank()) {
|
|
||||||
errorResponse(HttpStatusCode.BadRequest, "Password must not be null or blank")
|
|
||||||
return@post
|
|
||||||
}
|
|
||||||
call.respond(
|
|
||||||
userRepository.save(
|
|
||||||
User(
|
|
||||||
name = request.username,
|
|
||||||
password = request.password,
|
|
||||||
email = request.email
|
|
||||||
)
|
|
||||||
).asResponse()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
put("/{id}") {
|
put("/{id}") {
|
||||||
val session = call.principal<Session>()!!
|
val session = call.principal<Session>()!!
|
||||||
val request = call.receive<UserRequest>()
|
val request = call.receive<UserRequest>()
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package com.wbrawner.twigs.server.api
|
package com.wbrawner.twigs.server.api
|
||||||
|
|
||||||
import com.wbrawner.twigs.ErrorResponse
|
import com.wbrawner.twigs.*
|
||||||
import com.wbrawner.twigs.LoginRequest
|
|
||||||
import com.wbrawner.twigs.SessionResponse
|
|
||||||
import com.wbrawner.twigs.model.User
|
import com.wbrawner.twigs.model.User
|
||||||
import io.ktor.client.call.*
|
import io.ktor.client.call.*
|
||||||
import io.ktor.client.request.*
|
import io.ktor.client.request.*
|
||||||
|
@ -68,7 +66,7 @@ class UserRouteTest : ApiTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `login with valid credentials returns 200`() = apiTest { client ->
|
fun `login with valid username and password returns 200`() = apiTest { client ->
|
||||||
val users = listOf(
|
val users = listOf(
|
||||||
User(name = "testuser", password = "\$2a\$10\$bETxbFPja1PyXVLybETxb.CWBYzyYdZpmCcA7NSIN8dkdzidt1Xv2"),
|
User(name = "testuser", password = "\$2a\$10\$bETxbFPja1PyXVLybETxb.CWBYzyYdZpmCcA7NSIN8dkdzidt1Xv2"),
|
||||||
User(name = "otheruser", password = "\$2a\$10\$bETxbFPja1PyXVLybETxb..rhfIeOkP4qil1Drj29LDUhBxVkm6fS"),
|
User(name = "otheruser", password = "\$2a\$10\$bETxbFPja1PyXVLybETxb..rhfIeOkP4qil1Drj29LDUhBxVkm6fS"),
|
||||||
|
@ -86,7 +84,7 @@ class UserRouteTest : ApiTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `login with valid email returns 200`() = apiTest { client ->
|
fun `login with valid email and password returns 200`() = apiTest { client ->
|
||||||
val users = listOf(
|
val users = listOf(
|
||||||
User(
|
User(
|
||||||
name = "testuser",
|
name = "testuser",
|
||||||
|
@ -106,4 +104,112 @@ class UserRouteTest : ApiTest() {
|
||||||
assertEquals(users.first().id, session.userId)
|
assertEquals(users.first().id, session.userId)
|
||||||
assert(session.token.isNotBlank())
|
assert(session.token.isNotBlank())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `register with null username returns 400`() = apiTest { client ->
|
||||||
|
val request = UserRequest(password = "")
|
||||||
|
val response = client.post("/api/users/register") {
|
||||||
|
header("Content-Type", "application/json")
|
||||||
|
setBody(request)
|
||||||
|
}
|
||||||
|
assertEquals(HttpStatusCode.BadRequest, response.status)
|
||||||
|
val errorBody = response.body<ErrorResponse>()
|
||||||
|
assertEquals("Username must not be null or blank", errorBody.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `register with empty username returns 400`() = apiTest { client ->
|
||||||
|
val request = UserRequest(username = "", password = "")
|
||||||
|
val response = client.post("/api/users/register") {
|
||||||
|
header("Content-Type", "application/json")
|
||||||
|
setBody(request)
|
||||||
|
}
|
||||||
|
assertEquals(HttpStatusCode.BadRequest, response.status)
|
||||||
|
val errorBody = response.body<ErrorResponse>()
|
||||||
|
assertEquals("Username must not be null or blank", errorBody.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `register with null password returns 400`() = apiTest { client ->
|
||||||
|
val request = UserRequest(username = "test@example.com")
|
||||||
|
val response = client.post("/api/users/register") {
|
||||||
|
header("Content-Type", "application/json")
|
||||||
|
setBody(request)
|
||||||
|
}
|
||||||
|
assertEquals(HttpStatusCode.BadRequest, response.status)
|
||||||
|
val errorBody = response.body<ErrorResponse>()
|
||||||
|
assertEquals("Password must not be null or blank", errorBody.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `register with empty password returns 400`() = apiTest { client ->
|
||||||
|
val request = UserRequest(username = "test@example.com", password = "")
|
||||||
|
val response = client.post("/api/users/register") {
|
||||||
|
header("Content-Type", "application/json")
|
||||||
|
setBody(request)
|
||||||
|
}
|
||||||
|
assertEquals(HttpStatusCode.BadRequest, response.status)
|
||||||
|
val errorBody = response.body<ErrorResponse>()
|
||||||
|
assertEquals("Password must not be null or blank", errorBody.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `register with existing username returns 400`() = apiTest { client ->
|
||||||
|
val users = listOf(
|
||||||
|
User(
|
||||||
|
name = "testuser",
|
||||||
|
email = "test@example.com",
|
||||||
|
password = "\$2a\$10\$bETxbFPja1PyXVLybETxb.CWBYzyYdZpmCcA7NSIN8dkdzidt1Xv2"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
users.forEach { userRepository.save(it) }
|
||||||
|
val request = UserRequest(username = "testuser", password = "password")
|
||||||
|
val response = client.post("/api/users/register") {
|
||||||
|
header("Content-Type", "application/json")
|
||||||
|
setBody(request)
|
||||||
|
}
|
||||||
|
assertEquals(HttpStatusCode.BadRequest, response.status)
|
||||||
|
val errorBody = response.body<ErrorResponse>()
|
||||||
|
assertEquals("Username or email already taken", errorBody.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `register with existing email returns 400`() = apiTest { client ->
|
||||||
|
val users = listOf(
|
||||||
|
User(
|
||||||
|
name = "testuser",
|
||||||
|
email = "test@example.com",
|
||||||
|
password = "\$2a\$10\$bETxbFPja1PyXVLybETxb.CWBYzyYdZpmCcA7NSIN8dkdzidt1Xv2"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
users.forEach { userRepository.save(it) }
|
||||||
|
val request = UserRequest(username = "testuser2", email = "test@example.com", password = "password")
|
||||||
|
val response = client.post("/api/users/register") {
|
||||||
|
header("Content-Type", "application/json")
|
||||||
|
setBody(request)
|
||||||
|
}
|
||||||
|
assertEquals(HttpStatusCode.BadRequest, response.status)
|
||||||
|
val errorBody = response.body<ErrorResponse>()
|
||||||
|
assertEquals("Username or email already taken", errorBody.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `register with valid username and password returns 200`() = apiTest { client ->
|
||||||
|
val request = UserRequest("testuser", "testpassword")
|
||||||
|
val response = client.post("/api/users/register") {
|
||||||
|
header("Content-Type", "application/json")
|
||||||
|
setBody(request)
|
||||||
|
}
|
||||||
|
assertEquals(HttpStatusCode.OK, response.status)
|
||||||
|
val userResponse = response.body<UserResponse>()
|
||||||
|
assert(userResponse.id.isNotBlank())
|
||||||
|
assertEquals(request.username, userResponse.username)
|
||||||
|
assertEquals("", userResponse.email)
|
||||||
|
assertEquals(1, userRepository.entities.size)
|
||||||
|
val savedUser: User = userRepository.entities.first()
|
||||||
|
assertEquals(userResponse.id, savedUser.id)
|
||||||
|
assertEquals(request.username, savedUser.name)
|
||||||
|
assertEquals("", savedUser.email)
|
||||||
|
assertEquals("\$2a\$10\$bETxbFPja1PyXVLybETxb.CWBYzyYdZpmCcA7NSIN8dkdzidt1Xv2", savedUser.password)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@ data class User(
|
||||||
override val id: String = randomString(),
|
override val id: String = randomString(),
|
||||||
val name: String = "",
|
val name: String = "",
|
||||||
val password: String = "",
|
val password: String = "",
|
||||||
val email: String? = null
|
val email: String = ""
|
||||||
) : Principal, Identifiable
|
) : Principal, Identifiable
|
||||||
|
|
||||||
enum class Permission {
|
enum class Permission {
|
||||||
|
|
|
@ -5,11 +5,11 @@ import com.wbrawner.twigs.storage.UserRepository
|
||||||
|
|
||||||
class FakeUserRepository : FakeRepository<User>(), UserRepository {
|
class FakeUserRepository : FakeRepository<User>(), UserRepository {
|
||||||
override fun findAll(nameOrEmail: String, password: String?): List<User> {
|
override fun findAll(nameOrEmail: String, password: String?): List<User> {
|
||||||
return entities.filter {
|
return entities.filter { user ->
|
||||||
(it.name.equals(nameOrEmail, ignoreCase = true) || it.email.equals(
|
(user.name.equals(nameOrEmail, ignoreCase = true) || user.email.equals(
|
||||||
nameOrEmail,
|
nameOrEmail,
|
||||||
ignoreCase = true
|
ignoreCase = true
|
||||||
)) && it.password == password
|
)) && password?.let { user.password == it } ?: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue