Merge branch 'develop' into feat/spring-tests

This commit is contained in:
glashark
2026-05-03 20:08:31 +03:00
committed by GitHub
27 changed files with 1715 additions and 58 deletions
@@ -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,
)
@@ -1,6 +1,10 @@
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.domain.model.AuthProvider
import com.project.movienight.domain.model.User
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.stereotype.Repository
@@ -11,58 +15,80 @@ import java.util.UUID
class UserRepository(
private val jdbc: JdbcTemplate,
) : UserRepositoryPort {
private val userRowMapper = { rs: ResultSet, _: Int ->
User(
private val userEntityRowMapper = { rs: ResultSet, _: Int ->
UserEntity(
id = UUID.fromString(rs.getString("id")),
name = rs.getString("name"),
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 {
val entity = user.toEntity()
val updatedRows =
jdbc.update(
"""
UPDATE users
SET name = ?, email = ?
SET name = ?, email = ?, provider = ?, provider_id = ?
WHERE id = ?
""".trimIndent(),
user.name,
user.email,
user.id,
entity.name,
entity.email,
entity.provider,
entity.providerId,
entity.id,
)
if (updatedRows == 0) {
jdbc.update(
"""
INSERT INTO users (id, name, email)
VALUES (?, ?, ?)
INSERT INTO users (id, name, email, provider, provider_id, created_at)
VALUES (?, ?, ?, ?, ?, ?)
""".trimIndent(),
user.id,
user.name,
user.email,
entity.id,
entity.name,
entity.email,
entity.provider,
entity.providerId,
entity.createdAt,
)
}
return user
}
override fun findById(id: UUID): User? {
val users =
val entities =
jdbc.query(
"SELECT id, name, email FROM users WHERE id = ?",
userRowMapper,
"SELECT id, name, email, provider, provider_id, created_at FROM users WHERE id = ?",
userEntityRowMapper,
id,
)
return users.firstOrNull()
return entities.firstOrNull()?.toDomain()
}
override fun findAll(): List<User> =
jdbc.query(
"SELECT id, name, email FROM users",
userRowMapper,
)
"SELECT id, name, email, provider, provider_id, created_at FROM users",
userEntityRowMapper,
).map { it.toDomain() }
override fun deleteById(id: UUID) {
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()
}
}
@@ -57,11 +57,10 @@ class FilmController(
FilmResponse.fromDomain(
editFilmUseCase.edit(
id = id,
command =
EditFilmCommand(
title = request.title,
description = request.description,
),
command = EditFilmCommand(
title = request.title,
description = request.description,
),
),
)
@@ -8,8 +8,11 @@ import com.project.movienight.application.ports.input.CreateUserUseCase
import com.project.movienight.application.ports.input.DeleteUserUseCase
import com.project.movienight.application.ports.input.EditUserCommand
import com.project.movienight.application.ports.input.EditUserUseCase
import com.project.movienight.application.ports.input.GetAllUsersUseCase
import com.project.movienight.application.ports.input.GetUserByIdUseCase
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PatchMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
@@ -25,6 +28,8 @@ class UserController(
private val createUserUseCase: CreateUserUseCase,
private val editUserUseCase: EditUserUseCase,
private val deleteUserUseCase: DeleteUserUseCase,
private val getUserByIdUseCase: GetUserByIdUseCase,
private val getAllUsersUseCase: GetAllUsersUseCase,
) {
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
@@ -40,6 +45,16 @@ class UserController(
),
)
@GetMapping
fun getAll(): List<UserResponse> =
getAllUsersUseCase.getAll().map { UserResponse.fromDomain(it) }
@GetMapping("/{id}")
fun getById(
@PathVariable id: UUID,
): UserResponse =
UserResponse.fromDomain(getUserByIdUseCase.getById(id))
@PatchMapping("/{id}")
fun edit(
@PathVariable id: UUID,
@@ -48,10 +63,9 @@ class UserController(
UserResponse.fromDomain(
editUserUseCase.edit(
id = id,
command =
EditUserCommand(
name = request.name,
),
command = EditUserCommand(
name = request.name,
),
),
)
@@ -26,3 +26,11 @@ data class EditUserCommand(
interface DeleteUserUseCase {
fun delete(id: UUID)
}
interface GetUserByIdUseCase {
fun getById(id: UUID): User
}
interface GetAllUsersUseCase {
fun getAll(): List<User>
}
@@ -1,5 +1,6 @@
package com.project.movienight.application.ports.output
import com.project.movienight.domain.model.AuthProvider
import com.project.movienight.domain.model.User
import java.util.UUID
@@ -11,4 +12,9 @@ interface UserRepositoryPort {
fun findAll(): List<User>
fun deleteById(id: UUID)
fun findByProviderAndProviderId(
provider: AuthProvider,
providerId: String,
): User?
}
@@ -36,19 +36,15 @@ class FilmService(
throw BlockedValueException(target = "Film", field = "description")
}
val film =
Film(
id = idGenerator.generateId(),
title = command.title,
description = command.description,
)
val film = Film(
id = idGenerator.generateId(),
title = command.title,
description = command.description,
)
return filmRepository.save(film)
}
override fun edit(
id: UUID,
command: EditFilmCommand,
): Film {
override fun edit(id: UUID, command: EditFilmCommand): Film {
if (filmConfig.isBlocked(command.title)) {
throw BlockedValueException(target = "Film", field = "title")
}
@@ -5,6 +5,8 @@ import com.project.movienight.application.ports.input.CreateUserUseCase
import com.project.movienight.application.ports.input.DeleteUserUseCase
import com.project.movienight.application.ports.input.EditUserCommand
import com.project.movienight.application.ports.input.EditUserUseCase
import com.project.movienight.application.ports.input.GetAllUsersUseCase
import com.project.movienight.application.ports.input.GetUserByIdUseCase
import com.project.movienight.application.ports.output.IdGenerator
import com.project.movienight.application.ports.output.UserRepositoryPort
import com.project.movienight.config.UserServiceProperties
@@ -21,19 +23,21 @@ class UserService(
private val userConfig: UserServiceProperties,
) : CreateUserUseCase,
EditUserUseCase,
DeleteUserUseCase {
DeleteUserUseCase,
GetUserByIdUseCase,
GetAllUsersUseCase {
override fun create(command: CreateUserCommand): User {
if (userConfig.isBlocked(command.name)) {
throw BlockedValueException(target = "User", field = "name")
}
val user =
User(
id = idGenerator.generateId(),
name = command.name,
email = command.email,
library = null,
)
val user = User(
id = idGenerator.generateId(),
name = command.name,
email = command.email,
library = null,
)
return userRepository.save(user)
}
@@ -46,15 +50,18 @@ class UserService(
}
var user = userRepository.findById(id) ?: throw EntityNotFoundException(entity = "User", id = id.toString())
user = user.copy(name = command.name)
return userRepository.save(user)
}
override fun delete(id: UUID) {
userRepository.findById(id) ?: throw EntityNotFoundException(entity = "User", id = id.toString())
userRepository.deleteById(id)
}
override fun getById(id: UUID): User {
return userRepository.findById(id) ?: throw EntityNotFoundException(entity = "User", id = id.toString())
}
override fun getAll(): List<User> = userRepository.findAll()
}
@@ -0,0 +1,7 @@
package com.project.movienight.domain.model
enum class AuthProvider {
GOOGLE,
YANDEX,
VK,
}