Skip to content

Commit

Permalink
Push works
Browse files Browse the repository at this point in the history
  • Loading branch information
cheroliv committed Sep 30, 2024
1 parent 937d932 commit 01ac0fe
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 182 deletions.
20 changes: 17 additions & 3 deletions springboot/api/src/main/kotlin/webapp/users/UserDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import arrow.core.right
import org.springframework.beans.factory.getBean
import org.springframework.context.ApplicationContext
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate
import org.springframework.r2dbc.core.DatabaseClient
import org.springframework.r2dbc.core.awaitOne
import org.springframework.r2dbc.core.awaitRowsUpdated
import org.springframework.r2dbc.core.*
import webapp.core.model.EntityModel
import webapp.core.utils.AppUtils.cleanField
import webapp.users.UserDao.Attributes.EMAIL_ATTR
Expand Down Expand Up @@ -108,6 +106,17 @@ object UserDao {

object Dao {

suspend fun ApplicationContext.countUsers(): Int =
"SELECT COUNT(*) FROM `user`"
.let(getBean<DatabaseClient>()::sql)
.fetch()
.awaitSingle()
.values
.first()
.toString()
.toInt()


//TODO : change the return type in Either<Throwable, UUID>
suspend fun Pair<User, ApplicationContext>.save(): Either<Throwable, Long> = try {
second.getBean<R2dbcEntityTemplate>()
Expand All @@ -125,6 +134,11 @@ object UserDao {
e.left()
}

suspend fun ApplicationContext.deleteAllUsersOnly(): Unit =
"DELETE FROM `user`"
.let(getBean<DatabaseClient>()::sql)
.await()


suspend inline fun <reified T : EntityModel<*>> ApplicationContext.findOneByEmail(email: String): Either<Throwable, T> =
when (T::class) {
Expand Down
16 changes: 16 additions & 0 deletions springboot/api/src/main/kotlin/webapp/users/security/Role.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ package webapp.users.security

import jakarta.validation.constraints.NotNull
import jakarta.validation.constraints.Size
import org.springframework.beans.factory.getBean
import org.springframework.context.ApplicationContext
import org.springframework.r2dbc.core.DatabaseClient
import org.springframework.r2dbc.core.awaitSingle
import webapp.core.property.ROLE_ADMIN
import webapp.core.property.ROLE_ANONYMOUS
import webapp.core.property.ROLE_USER
Expand Down Expand Up @@ -33,5 +37,17 @@ data class Role(
('$ROLE_ANONYMOUS');
"""
}

object Dao {
suspend fun ApplicationContext.countRoles(): Int =
"select count(*) from `authority`"
.let(getBean<DatabaseClient>()::sql)
.fetch()
.awaitSingle()
.values
.first()
.toString()
.toInt()
}
}
}
60 changes: 58 additions & 2 deletions springboot/api/src/main/kotlin/webapp/users/security/UserRole.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
package webapp.users.security

import jakarta.validation.constraints.NotNull
import org.springframework.beans.factory.getBean
import org.springframework.context.ApplicationContext
import org.springframework.r2dbc.core.DatabaseClient
import org.springframework.r2dbc.core.await
import org.springframework.r2dbc.core.awaitSingle
import webapp.users.UserDao
import webapp.users.security.Role.RoleDao
import webapp.users.security.UserRole.UserRoleDao.Fields.ID_FIELD
Expand Down Expand Up @@ -57,7 +62,58 @@ data class UserRole(
// """
}

// object Dao {
object Dao {
suspend fun ApplicationContext.countUserAuthority(): Int =
"select count(*) from `user_authority`"
.let(getBean<DatabaseClient>()::sql)
.fetch()
.awaitSingle()
.values
.first()
.toString()
.toInt()


suspend fun ApplicationContext.deleteAllUserAuthorities(): Unit =
"DELETE FROM `user_authority`"
.let(getBean<DatabaseClient>()::sql)
.await()

suspend fun ApplicationContext.deleteAllUserAuthorityByUserId(
id: UUID
) = "delete from user_authority where user_id = :userId"
.let(getBean<DatabaseClient>()::sql)
.bind("userId", id)
.await()

suspend fun ApplicationContext.deleteAuthorityByRole(
role: String
): Unit = "delete from `authority` a where lower(a.role) = lower(:role)"
.let(getBean<DatabaseClient>()::sql)
.bind("role", role)
.await()

suspend fun ApplicationContext.deleteUserByIdWithAuthorities_(id: UUID) = getBean<DatabaseClient>().run {
"delete from user_authority where user_id = :userId"
.let(::sql)
.bind("userId", id)
.await()
"delete from `user` where user_id = :userId"
.let(::sql)
.await()
}

val ApplicationContext.queryDeleteAllUserAuthorityByUserLogin
get() =
"delete from user_authority where user_id = (select u.id from `user` u where u.login=:login)"

suspend fun ApplicationContext.deleteAllUserAuthorityByUserLogin(
login: String
): Unit = getBean<DatabaseClient>()
.sql(queryDeleteAllUserAuthorityByUserLogin)
.bind("login", login)
.await()

// val Pair<User, ApplicationContext>.toJson: String
// get() = second.getBean<ObjectMapper>().writeValueAsString(first)
//
Expand Down Expand Up @@ -88,6 +144,6 @@ data class UserRole(
// } catch (e: Throwable) {
// e.left()
// }
// }
}
}
}
91 changes: 4 additions & 87 deletions springboot/api/src/test/kotlin/tdd/TestUtils.kt
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
@file:Suppress(
"IdentifierGrammar",
"MemberVisibilityCanBePrivate",
"unused"
"unused", "UNUSED_VARIABLE"
)

package tdd

import org.springframework.beans.factory.getBean
import org.springframework.context.ApplicationContext
import org.springframework.r2dbc.core.DatabaseClient
import org.springframework.r2dbc.core.await
import org.springframework.r2dbc.core.awaitSingle
import webapp.core.property.*
import webapp.users.User
import java.time.Instant
import java.time.Instant.now
import java.util.*
import java.util.UUID.randomUUID
import java.util.regex.Pattern
import kotlin.test.assertEquals

Expand All @@ -33,8 +28,8 @@ object TestUtils {
"password": "$USER"}"""

fun userFactory(login: String): User {
val now: Instant = now()
val uuid = UUID.randomUUID()
val now = now()
val uuid = randomUUID()
return User(
password = login,
login = login,
Expand All @@ -52,87 +47,9 @@ object TestUtils {
val ApplicationContext.languages
get() = setOf("en", "fr", "de", "it", "es")

val ApplicationContext.queryDeleteAllUserAuthorityByUserLogin
get() =
"delete from user_authority where user_id = (select u.id from `user` u where u.login=:login)"

val ApplicationContext.defaultRoles
get() = setOf(ROLE_ADMIN, ROLE_USER, ROLE_ANONYMOUS)




suspend fun ApplicationContext.countUsers(): Int =
"select count(*) from `user`"
.let(getBean<DatabaseClient>()::sql)
.fetch()
.awaitSingle()
.values
.first()
.toString()
.toInt()

suspend fun ApplicationContext.countRoles(): Int =
"select count(*) from `authority`"
.let(getBean<DatabaseClient>()::sql)
.fetch()
.awaitSingle()
.values
.first()
.toString()
.toInt()

suspend fun ApplicationContext.countUserAuthority(): Int =
"select count(*) from `user_authority`"
.let(getBean<DatabaseClient>()::sql)
.fetch()
.awaitSingle()
.values
.first()
.toString()
.toInt()

suspend fun ApplicationContext.deleteAllUsersOnly(): Unit =
"delete from `user`"
.let(getBean<DatabaseClient>()::sql)
.await()

suspend fun ApplicationContext.deleteAllUserAuthorities(): Unit =
"delete from user_authority"
.let(getBean<DatabaseClient>()::sql)
.await()

suspend fun ApplicationContext.deleteAllUserAuthorityByUserId(
id: UUID
) = "delete from user_authority where user_id = :userId"
.let(getBean<DatabaseClient>()::sql)
.bind("userId", id)
.await()

suspend fun ApplicationContext.deleteAuthorityByRole(
role: String
): Unit = "delete from `authority` a where lower(a.role) = lower(:role)"
.let(getBean<DatabaseClient>()::sql)
.bind("role", role)
.await()

suspend fun ApplicationContext.deleteUserByIdWithAuthorities_(id: UUID) = getBean<DatabaseClient>().run {
"delete from user_authority where user_id = :userId"
.let(::sql)
.bind("userId", id)
.await()
"delete from `user` where user_id = :userId"
.let(::sql)
.await()
}

suspend fun ApplicationContext.deleteAllUserAuthorityByUserLogin(
login: String
): Unit = getBean<DatabaseClient>()
.sql(queryDeleteAllUserAuthorityByUserLogin)
.bind("login", login)
.await()

fun ApplicationContext.checkProperty(
property: String,
value: String,
Expand Down
65 changes: 29 additions & 36 deletions springboot/api/src/test/kotlin/webapp/users/UserDaoTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ import org.springframework.context.ApplicationContext
import org.springframework.dao.EmptyResultDataAccessException
import org.springframework.test.context.ActiveProfiles
import tdd.TestUtils.Data.user
import tdd.TestUtils.countRoles
import tdd.TestUtils.countUsers
import tdd.TestUtils.defaultRoles
import tdd.TestUtils.deleteAllUsersOnly
import webapp.core.model.EntityModel.Members.withId
import webapp.core.utils.AppUtils.cleanField
import webapp.core.utils.AppUtils.toJson
import webapp.core.utils.i
import webapp.users.UserDao.Dao.countUsers
import webapp.users.UserDao.Dao.deleteAllUsersOnly
import webapp.users.UserDao.Dao.findOneByEmail
import webapp.users.UserDao.Dao.save
import webapp.users.security.Role.RoleDao.Dao.countRoles
import kotlin.test.*


Expand All @@ -39,22 +39,15 @@ class UserDaoTests {
fun cleanUp() = runBlocking { context.deleteAllUsersOnly() }

@Test
fun `save default user should work in this context `() = runBlocking {
val count = context.countUsers()
(user to context).save()
assertEquals(expected = count + 1, context.countUsers())
fun `count users, expected 0`() = runBlocking {
assertEquals(
0,
context.countUsers(),
"because init sql script does not inserts default users."
)
}

@Test
fun `count users, expected 0`() =
runBlocking {
assertEquals(
0,
context.countUsers(),
"because init sql script does not inserts default users."
)
}

//TODO: move this test RoleDaoTests
@Test
fun `count roles, expected 3`() = runBlocking {
context.run {
Expand All @@ -67,27 +60,19 @@ class UserDaoTests {
}

@Test
fun `display user formatted in JSON`() = assertDoesNotThrow {
(user to context).toJson.let(::i)
}

@Test
fun `check toJson build a valid json format`(): Unit = assertDoesNotThrow {
(user to context).toJson.let(mapper::readTree)
fun `save default user should work in this context `() = runBlocking {
val count = context.countUsers()
(user to context).save()
assertEquals(expected = count + 1, context.countUsers())
}


@Test
fun `test cleanField extension function`() = assertEquals(
"login",
"`login`".cleanField(),
"Backtick should be removed"
)


@Test
fun `check findOneByEmail with non-existent email`(): Unit = runBlocking {
assertEquals(0, context.countUsers(), "context should not have a user recorded in database")
assertEquals(
0,
context.countUsers(),
"context should not have a user recorded in database"
)
context.findOneByEmail<User>("user@dummy.com").apply {
assertFalse(isRight())
assertTrue(isLeft())
Expand All @@ -97,9 +82,17 @@ class UserDaoTests {

@Test
fun `check findOneByEmail with existant email`(): Unit = runBlocking {
assertEquals(0, context.countUsers(), "context should not have a user recorded in database")
assertEquals(
0,
context.countUsers(),
"context should not have a user recorded in database"
)
(user to context).save()
assertEquals(1, context.countUsers(), "context should have only one user recorded in database")
assertEquals(
1,
context.countUsers(),
"context should have only one user recorded in database"
)
context.findOneByEmail<User>(user.email).apply {
assertTrue(isRight())
assertFalse(isLeft())
Expand Down
Loading

0 comments on commit 01ac0fe

Please sign in to comment.