Merge pull request #23 from devitq/feat/user-entity-21
feat: user entity 21
This commit was merged in pull request #23.
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
package com.project.movienight.adapters.persistence.entity
|
||||||
|
|
||||||
|
import com.project.movienight.domain.model.AuthProvider
|
||||||
|
import com.project.movienight.domain.model.User
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
data class UserEntity(
|
||||||
|
val id: UUID,
|
||||||
|
val name: String,
|
||||||
|
val email: String,
|
||||||
|
val provider: String?,
|
||||||
|
val providerId: String?,
|
||||||
|
val createdAt: LocalDateTime,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun UserEntity.toDomain(): User =
|
||||||
|
User(
|
||||||
|
id = id,
|
||||||
|
name = name,
|
||||||
|
email = email,
|
||||||
|
library = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun User.toEntity(
|
||||||
|
provider: AuthProvider? = null,
|
||||||
|
providerId: String? = null,
|
||||||
|
createdAt: LocalDateTime = LocalDateTime.now(),
|
||||||
|
): UserEntity =
|
||||||
|
UserEntity(
|
||||||
|
id = id,
|
||||||
|
name = name,
|
||||||
|
email = email,
|
||||||
|
provider = provider?.name,
|
||||||
|
providerId = providerId,
|
||||||
|
createdAt = createdAt,
|
||||||
|
)
|
||||||
+45
-19
@@ -1,6 +1,10 @@
|
|||||||
package com.project.movienight.adapters.persistence.jdbc
|
package com.project.movienight.adapters.persistence.jdbc
|
||||||
|
|
||||||
|
import com.project.movienight.adapters.persistence.entity.UserEntity
|
||||||
|
import com.project.movienight.adapters.persistence.entity.toDomain
|
||||||
|
import com.project.movienight.adapters.persistence.entity.toEntity
|
||||||
import com.project.movienight.application.ports.output.UserRepositoryPort
|
import com.project.movienight.application.ports.output.UserRepositoryPort
|
||||||
|
import com.project.movienight.domain.model.AuthProvider
|
||||||
import com.project.movienight.domain.model.User
|
import com.project.movienight.domain.model.User
|
||||||
import org.springframework.jdbc.core.JdbcTemplate
|
import org.springframework.jdbc.core.JdbcTemplate
|
||||||
import org.springframework.stereotype.Repository
|
import org.springframework.stereotype.Repository
|
||||||
@@ -11,58 +15,80 @@ import java.util.UUID
|
|||||||
class UserRepository(
|
class UserRepository(
|
||||||
private val jdbc: JdbcTemplate,
|
private val jdbc: JdbcTemplate,
|
||||||
) : UserRepositoryPort {
|
) : UserRepositoryPort {
|
||||||
private val userRowMapper = { rs: ResultSet, _: Int ->
|
private val userEntityRowMapper = { rs: ResultSet, _: Int ->
|
||||||
User(
|
UserEntity(
|
||||||
id = UUID.fromString(rs.getString("id")),
|
id = UUID.fromString(rs.getString("id")),
|
||||||
name = rs.getString("name"),
|
name = rs.getString("name"),
|
||||||
email = rs.getString("email"),
|
email = rs.getString("email"),
|
||||||
library = null,
|
provider = rs.getString("provider"),
|
||||||
|
providerId = rs.getString("provider_id"),
|
||||||
|
createdAt = rs.getTimestamp("created_at").toLocalDateTime(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun save(user: User): User {
|
override fun save(user: User): User {
|
||||||
|
val entity = user.toEntity()
|
||||||
val updatedRows =
|
val updatedRows =
|
||||||
jdbc.update(
|
jdbc.update(
|
||||||
"""
|
"""
|
||||||
UPDATE users
|
UPDATE users
|
||||||
SET name = ?, email = ?
|
SET name = ?, email = ?, provider = ?, provider_id = ?
|
||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
user.name,
|
entity.name,
|
||||||
user.email,
|
entity.email,
|
||||||
user.id,
|
entity.provider,
|
||||||
|
entity.providerId,
|
||||||
|
entity.id,
|
||||||
)
|
)
|
||||||
if (updatedRows == 0) {
|
if (updatedRows == 0) {
|
||||||
jdbc.update(
|
jdbc.update(
|
||||||
"""
|
"""
|
||||||
INSERT INTO users (id, name, email)
|
INSERT INTO users (id, name, email, provider, provider_id, created_at)
|
||||||
VALUES (?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?)
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
user.id,
|
entity.id,
|
||||||
user.name,
|
entity.name,
|
||||||
user.email,
|
entity.email,
|
||||||
|
entity.provider,
|
||||||
|
entity.providerId,
|
||||||
|
entity.createdAt,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findById(id: UUID): User? {
|
override fun findById(id: UUID): User? {
|
||||||
val users =
|
val entities =
|
||||||
jdbc.query(
|
jdbc.query(
|
||||||
"SELECT id, name, email FROM users WHERE id = ?",
|
"SELECT id, name, email, provider, provider_id, created_at FROM users WHERE id = ?",
|
||||||
userRowMapper,
|
userEntityRowMapper,
|
||||||
id,
|
id,
|
||||||
)
|
)
|
||||||
return users.firstOrNull()
|
return entities.firstOrNull()?.toDomain()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findAll(): List<User> =
|
override fun findAll(): List<User> =
|
||||||
jdbc.query(
|
jdbc.query(
|
||||||
"SELECT id, name, email FROM users",
|
"SELECT id, name, email, provider, provider_id, created_at FROM users",
|
||||||
userRowMapper,
|
userEntityRowMapper,
|
||||||
)
|
).map { it.toDomain() }
|
||||||
|
|
||||||
override fun deleteById(id: UUID) {
|
override fun deleteById(id: UUID) {
|
||||||
jdbc.update("DELETE FROM users WHERE id = ?", id)
|
jdbc.update("DELETE FROM users WHERE id = ?", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findByProviderAndProviderId(
|
||||||
|
provider: AuthProvider,
|
||||||
|
providerId: String,
|
||||||
|
): User? {
|
||||||
|
val entities =
|
||||||
|
jdbc.query(
|
||||||
|
"SELECT id, name, email, provider, provider_id, created_at FROM users WHERE provider = ? AND provider_id = ?",
|
||||||
|
userEntityRowMapper,
|
||||||
|
provider.name,
|
||||||
|
providerId,
|
||||||
|
)
|
||||||
|
return entities.firstOrNull()?.toDomain()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.project.movienight.application.ports.output
|
package com.project.movienight.application.ports.output
|
||||||
|
|
||||||
|
import com.project.movienight.domain.model.AuthProvider
|
||||||
import com.project.movienight.domain.model.User
|
import com.project.movienight.domain.model.User
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@@ -11,4 +12,9 @@ interface UserRepositoryPort {
|
|||||||
fun findAll(): List<User>
|
fun findAll(): List<User>
|
||||||
|
|
||||||
fun deleteById(id: UUID)
|
fun deleteById(id: UUID)
|
||||||
|
|
||||||
|
fun findByProviderAndProviderId(
|
||||||
|
provider: AuthProvider,
|
||||||
|
providerId: String,
|
||||||
|
): User?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.project.movienight.domain.model
|
||||||
|
|
||||||
|
enum class AuthProvider {
|
||||||
|
GOOGLE,
|
||||||
|
YANDEX,
|
||||||
|
VK,
|
||||||
|
}
|
||||||
+81
@@ -0,0 +1,81 @@
|
|||||||
|
package com.project.movienight.adapters.persistence.entity
|
||||||
|
|
||||||
|
import com.project.movienight.domain.model.AuthProvider
|
||||||
|
import com.project.movienight.domain.model.User
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.util.UUID
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNull
|
||||||
|
|
||||||
|
class UserEntityMappingTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `toDomain maps UserEntity correctly`() {
|
||||||
|
val entity = UserEntity(
|
||||||
|
id = UUID.randomUUID(),
|
||||||
|
name = "John Pork",
|
||||||
|
email = "john@email.com",
|
||||||
|
provider = "GOOGLE",
|
||||||
|
providerId = "google1234",
|
||||||
|
createdAt = LocalDateTime.now(),
|
||||||
|
)
|
||||||
|
val user = entity.toDomain()
|
||||||
|
|
||||||
|
assertEquals(entity.id, user.id)
|
||||||
|
assertEquals(entity.name, user.name)
|
||||||
|
assertEquals(entity.email, user.email)
|
||||||
|
assertNull(user.library)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `toEntity maps User with OAuth provider`() {
|
||||||
|
val user = User(
|
||||||
|
id = UUID.randomUUID(),
|
||||||
|
name = "Jane",
|
||||||
|
email = "jane@mail.com",
|
||||||
|
library = null
|
||||||
|
)
|
||||||
|
|
||||||
|
val entity = user.toEntity(AuthProvider.YANDEX, "yandex456")
|
||||||
|
|
||||||
|
assertEquals(user.id, entity.id)
|
||||||
|
assertEquals(user.name, entity.name)
|
||||||
|
assertEquals(user.email, entity.email)
|
||||||
|
assertEquals("YANDEX", entity.provider)
|
||||||
|
assertEquals("yandex456", entity.providerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `toEntity maps User without OAuth provider`() {
|
||||||
|
val user = User(
|
||||||
|
id = UUID.randomUUID(),
|
||||||
|
name = "Bob",
|
||||||
|
email = "bob@mail.com",
|
||||||
|
library = null
|
||||||
|
)
|
||||||
|
|
||||||
|
val entity = user.toEntity()
|
||||||
|
|
||||||
|
assertNull(entity.provider)
|
||||||
|
assertNull(entity.providerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `mapping is reversible for basic fields`() {
|
||||||
|
val original = User(
|
||||||
|
id = UUID.randomUUID(),
|
||||||
|
name = "Alice",
|
||||||
|
email = "alice@email.com",
|
||||||
|
library = null
|
||||||
|
)
|
||||||
|
|
||||||
|
val mapped = original.toEntity().toDomain()
|
||||||
|
|
||||||
|
assertEquals(original.id, mapped.id)
|
||||||
|
assertEquals(original.name, mapped.name)
|
||||||
|
assertEquals(original.email, mapped.email)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user