develop #29
|
@ -1,8 +1,9 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.files;
|
||||
package dev.fyloz.colorrecipesexplorer.logic.files;
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.logic.RecipeLogic;
|
||||
import dev.fyloz.colorrecipesexplorer.model.Recipe;
|
||||
import dev.fyloz.colorrecipesexplorer.service.RecipeService;
|
||||
import dev.fyloz.colorrecipesexplorer.xlsx.XlsxExporter;
|
||||
import mu.KotlinLogging;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
@ -17,14 +18,12 @@ import java.util.zip.ZipOutputStream;
|
|||
@Service
|
||||
@Profile("!emergency")
|
||||
public class XlsService {
|
||||
|
||||
private final RecipeService recipeService;
|
||||
private final Logger logger;
|
||||
private final RecipeLogic recipeService;
|
||||
private final Logger logger = KotlinLogging.INSTANCE.logger("XlsService");
|
||||
|
||||
@Autowired
|
||||
public XlsService(RecipeService recipeService, Logger logger) {
|
||||
this.recipeService = recipeService;
|
||||
this.logger = logger;
|
||||
public XlsService(RecipeLogic recipeLogic) {
|
||||
this.recipeService = recipeLogic;
|
||||
}
|
||||
|
||||
/**
|
|
@ -3,9 +3,9 @@ package dev.fyloz.colorrecipesexplorer
|
|||
import dev.fyloz.colorrecipesexplorer.databasemanager.CreDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.databasemanager.databaseContext
|
||||
import dev.fyloz.colorrecipesexplorer.databasemanager.databaseUpdaterProperties
|
||||
import dev.fyloz.colorrecipesexplorer.model.Configuration
|
||||
import dev.fyloz.colorrecipesexplorer.logic.config.ConfigurationLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.ConfigurationType
|
||||
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService
|
||||
import mu.KotlinLogging
|
||||
import org.slf4j.Logger
|
||||
import org.springframework.boot.jdbc.DataSourceBuilder
|
||||
import org.springframework.context.annotation.Bean
|
||||
|
@ -23,11 +23,12 @@ val DATABASE_NAME_REGEX = Regex("(\\w+)$")
|
|||
@SpringConfiguration
|
||||
@DependsOn("configurationsInitializer", "configurationService")
|
||||
class DataSourceConfiguration {
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
@Bean(name = ["dataSource"])
|
||||
fun customDataSource(
|
||||
logger: Logger,
|
||||
environment: ConfigurableEnvironment,
|
||||
configurationService: ConfigurationService
|
||||
configurationService: ConfigurationLogic
|
||||
): DataSource {
|
||||
fun getConfiguration(type: ConfigurationType) =
|
||||
if (type.secure) configurationService.getSecure(type)
|
||||
|
|
|
@ -4,10 +4,10 @@ import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
|||
import dev.fyloz.colorrecipesexplorer.config.initializers.AbstractInitializer
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties
|
||||
import dev.fyloz.colorrecipesexplorer.emergencyMode
|
||||
import dev.fyloz.colorrecipesexplorer.logic.config.ConfigurationLogic
|
||||
import dev.fyloz.colorrecipesexplorer.rest.CRE_PROPERTIES
|
||||
import dev.fyloz.colorrecipesexplorer.restartApplication
|
||||
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService
|
||||
import org.slf4j.Logger
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent
|
||||
import org.springframework.context.ApplicationListener
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
@ -20,10 +20,11 @@ import kotlin.concurrent.thread
|
|||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
@RequireDatabase
|
||||
class ApplicationReadyListener(
|
||||
private val configurationService: ConfigurationService,
|
||||
private val creProperties: CreProperties,
|
||||
private val logger: Logger
|
||||
private val configurationLogic: ConfigurationLogic,
|
||||
private val creProperties: CreProperties
|
||||
) : AbstractInitializer() {
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
override fun initialize() {
|
||||
if (emergencyMode) {
|
||||
logger.error("Emergency mode is enabled, default material types will not be created")
|
||||
|
@ -40,17 +41,17 @@ class ApplicationReadyListener(
|
|||
}
|
||||
|
||||
private fun initDatabaseConfigurations() {
|
||||
configurationService.initializeProperties { !it.file }
|
||||
configurationLogic.initializeProperties { !it.file }
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration("configurationsInitializer")
|
||||
class ConfigurationsInitializer(
|
||||
private val configurationService: ConfigurationService
|
||||
private val configurationLogic: ConfigurationLogic
|
||||
) {
|
||||
@PostConstruct
|
||||
fun initializeFileConfigurations() {
|
||||
configurationService.initializeProperties { it.file }
|
||||
configurationLogic.initializeProperties { it.file }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ package dev.fyloz.colorrecipesexplorer.config
|
|||
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.MaterialTypeProperties
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.CachedFileSystemItem
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.CachedFileSystemItem
|
||||
import dev.fyloz.memorycache.ExpiringMemoryCache
|
||||
import dev.fyloz.memorycache.MemoryCache
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
|
@ -13,6 +13,6 @@ import org.springframework.context.annotation.Configuration
|
|||
@EnableConfigurationProperties(MaterialTypeProperties::class, CreProperties::class)
|
||||
class CreConfiguration(private val creProperties: CreProperties) {
|
||||
@Bean
|
||||
fun fileCache(): MemoryCache<String, CachedFileSystemItem> =
|
||||
fun fileMemoryCache(): MemoryCache<String, CachedFileSystemItem> =
|
||||
ExpiringMemoryCache(maxAccessCount = creProperties.fileCacheMaxAccessCount)
|
||||
}
|
||||
|
|
|
@ -2,16 +2,15 @@ package dev.fyloz.colorrecipesexplorer.config.initializers
|
|||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.MaterialTypeProperties
|
||||
import dev.fyloz.colorrecipesexplorer.logic.MaterialTypeLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.MaterialType
|
||||
import dev.fyloz.colorrecipesexplorer.model.materialType
|
||||
import dev.fyloz.colorrecipesexplorer.service.MaterialTypeService
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
||||
@Configuration
|
||||
@RequireDatabase
|
||||
class MaterialTypeInitializer(
|
||||
private val materialTypeService: MaterialTypeService,
|
||||
private val materialTypeLogic: MaterialTypeLogic,
|
||||
private val materialTypeProperties: MaterialTypeProperties
|
||||
) : AbstractInitializer() {
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
@ -24,21 +23,21 @@ class MaterialTypeInitializer(
|
|||
|
||||
private fun ensureSystemMaterialTypesExists() {
|
||||
val systemTypes = materialTypeProperties.systemTypes.map { it.toMaterialType() }
|
||||
val oldSystemTypes = materialTypeService.getAllSystemTypes().toMutableSet()
|
||||
val oldSystemTypes = materialTypeLogic.getAllSystemTypes().toMutableSet()
|
||||
|
||||
fun saveOrUpdateSystemType(type: MaterialType) {
|
||||
if (materialTypeService.existsByName(type.name)) {
|
||||
with(materialTypeService.getByName(type.name)) {
|
||||
if (materialTypeLogic.existsByName(type.name)) {
|
||||
with(materialTypeLogic.getByName(type.name)) {
|
||||
if (!this.systemType) {
|
||||
logger.info("Material type '${type.name}' already exists and will be flagged as a system type")
|
||||
materialTypeService.update(this.copy(systemType = true))
|
||||
materialTypeLogic.update(this.copy(systemType = true))
|
||||
} else {
|
||||
logger.debug("System material type '${type.name}' already exists")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.info("System material type '${type.name}' will be created")
|
||||
materialTypeService.save(type)
|
||||
materialTypeLogic.save(type)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +50,7 @@ class MaterialTypeInitializer(
|
|||
// Remove old system types
|
||||
oldSystemTypes.forEach {
|
||||
logger.info("Material type '${it.name}' is not a system type anymore")
|
||||
materialTypeService.updateSystemType(it.copy(systemType = false))
|
||||
materialTypeLogic.updateSystemType(it.copy(systemType = false))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
package dev.fyloz.colorrecipesexplorer.config.initializers
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.logic.MixLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.Mix
|
||||
import dev.fyloz.colorrecipesexplorer.model.MixMaterial
|
||||
import dev.fyloz.colorrecipesexplorer.service.MixService
|
||||
import dev.fyloz.colorrecipesexplorer.utils.merge
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
@ -12,7 +12,7 @@ import java.util.*
|
|||
@Configuration
|
||||
@RequireDatabase
|
||||
class MixInitializer(
|
||||
private val mixService: MixService
|
||||
private val mixLogic: MixLogic
|
||||
) : AbstractInitializer() {
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
|
@ -24,7 +24,7 @@ class MixInitializer(
|
|||
private fun fixAllPositions() {
|
||||
logger.debug("Validating mix materials positions...")
|
||||
|
||||
mixService.getAll()
|
||||
mixLogic.getAll()
|
||||
.filter { mix -> mix.mixMaterials.any { it.position == 0 } }
|
||||
.forEach(this::fixMixPositions)
|
||||
|
||||
|
@ -48,7 +48,7 @@ class MixInitializer(
|
|||
val updatedMixMaterials = mix.mixMaterials.merge(fixedMixMaterials)
|
||||
|
||||
with(mix.copy(mixMaterials = updatedMixMaterials.toMutableSet())) {
|
||||
mixService.update(this)
|
||||
mixLogic.update(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package dev.fyloz.colorrecipesexplorer.config.initializers
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.logic.RecipeLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.Recipe
|
||||
import dev.fyloz.colorrecipesexplorer.model.RecipeGroupInformation
|
||||
import dev.fyloz.colorrecipesexplorer.model.RecipeStep
|
||||
import dev.fyloz.colorrecipesexplorer.service.RecipeService
|
||||
import dev.fyloz.colorrecipesexplorer.utils.merge
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
@ -12,7 +12,7 @@ import org.springframework.context.annotation.Configuration
|
|||
@Configuration
|
||||
@RequireDatabase
|
||||
class RecipeInitializer(
|
||||
private val recipeService: RecipeService
|
||||
private val recipeLogic: RecipeLogic
|
||||
) : AbstractInitializer() {
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
|
@ -24,7 +24,7 @@ class RecipeInitializer(
|
|||
private fun fixAllPositions() {
|
||||
logger.debug("Validating recipes steps positions...")
|
||||
|
||||
recipeService.getAll()
|
||||
recipeLogic.getAll()
|
||||
.forEach(this::fixRecipePositions)
|
||||
|
||||
logger.debug("Recipes steps positions are valid!")
|
||||
|
@ -39,7 +39,7 @@ class RecipeInitializer(
|
|||
val updatedGroupInformation = recipe.groupsInformation.merge(fixedGroupInformation)
|
||||
|
||||
with(recipe.copy(groupsInformation = updatedGroupInformation.toMutableSet())) {
|
||||
recipeService.update(this)
|
||||
recipeLogic.update(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,12 @@ package dev.fyloz.colorrecipesexplorer.config.security
|
|||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties
|
||||
import dev.fyloz.colorrecipesexplorer.exception.NotFoundException
|
||||
import dev.fyloz.colorrecipesexplorer.logic.users.JwtLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.users.UserDetailsLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.UserDetails
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.UserLoginRequest
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.UserOutputDto
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.toAuthorities
|
||||
import dev.fyloz.colorrecipesexplorer.service.users.JwtService
|
||||
import dev.fyloz.colorrecipesexplorer.service.users.UserDetailsService
|
||||
import dev.fyloz.colorrecipesexplorer.utils.addCookie
|
||||
import io.jsonwebtoken.ExpiredJwtException
|
||||
import org.springframework.security.authentication.AuthenticationManager
|
||||
|
@ -28,7 +28,7 @@ val blacklistedJwtTokens = mutableListOf<String>() // Not working, move to a ca
|
|||
|
||||
class JwtAuthenticationFilter(
|
||||
private val authManager: AuthenticationManager,
|
||||
private val jwtService: JwtService,
|
||||
private val jwtLogic: JwtLogic,
|
||||
private val securityProperties: CreSecurityProperties,
|
||||
private val updateUserLoginTime: (Long) -> Unit
|
||||
) : UsernamePasswordAuthenticationFilter() {
|
||||
|
@ -52,7 +52,7 @@ class JwtAuthenticationFilter(
|
|||
auth: Authentication
|
||||
) {
|
||||
val userDetails = auth.principal as UserDetails
|
||||
val token = jwtService.buildJwt(userDetails)
|
||||
val token = jwtLogic.buildJwt(userDetails)
|
||||
|
||||
with(userDetails.user) {
|
||||
logger.info("User ${this.id} (${this.firstName} ${this.lastName}) has logged in successfully")
|
||||
|
@ -72,9 +72,9 @@ class JwtAuthenticationFilter(
|
|||
}
|
||||
|
||||
class JwtAuthorizationFilter(
|
||||
private val jwtService: JwtService,
|
||||
private val jwtLogic: JwtLogic,
|
||||
authenticationManager: AuthenticationManager,
|
||||
private val userDetailsService: UserDetailsService
|
||||
private val userDetailsLogic: UserDetailsLogic
|
||||
) : BasicAuthenticationFilter(authenticationManager) {
|
||||
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) {
|
||||
fun tryLoginFromBearer(): Boolean {
|
||||
|
@ -109,7 +109,7 @@ class JwtAuthorizationFilter(
|
|||
|
||||
private fun getAuthentication(token: String): UsernamePasswordAuthenticationToken? {
|
||||
return try {
|
||||
val user = jwtService.parseJwt(token.replace("Bearer", ""))
|
||||
val user = jwtLogic.parseJwt(token.replace("Bearer", ""))
|
||||
getAuthenticationToken(user)
|
||||
} catch (_: ExpiredJwtException) {
|
||||
null
|
||||
|
@ -120,7 +120,7 @@ class JwtAuthorizationFilter(
|
|||
UsernamePasswordAuthenticationToken(user.id, null, user.permissions.toAuthorities())
|
||||
|
||||
private fun getAuthenticationToken(userId: Long): UsernamePasswordAuthenticationToken? = try {
|
||||
val userDetails = userDetailsService.loadUserById(userId)
|
||||
val userDetails = userDetailsLogic.loadUserById(userId)
|
||||
UsernamePasswordAuthenticationToken(userDetails.username, null, userDetails.authorities)
|
||||
} catch (_: NotFoundException) {
|
||||
null
|
||||
|
|
|
@ -2,12 +2,11 @@ package dev.fyloz.colorrecipesexplorer.config.security
|
|||
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties
|
||||
import dev.fyloz.colorrecipesexplorer.emergencyMode
|
||||
import dev.fyloz.colorrecipesexplorer.logic.users.JwtLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.users.UserDetailsLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.users.UserLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.Permission
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.User
|
||||
import dev.fyloz.colorrecipesexplorer.service.users.JwtService
|
||||
import dev.fyloz.colorrecipesexplorer.service.users.UserDetailsService
|
||||
import dev.fyloz.colorrecipesexplorer.service.users.UserService
|
||||
import mu.KLogger
|
||||
import mu.KotlinLogging
|
||||
import org.slf4j.Logger
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
|
@ -38,8 +37,8 @@ private const val rootUserFirstName = "Root"
|
|||
private const val rootUserLastName = "User"
|
||||
|
||||
abstract class BaseSecurityConfig(
|
||||
private val userDetailsService: UserDetailsService,
|
||||
private val jwtService: JwtService,
|
||||
private val userDetailsLogic: UserDetailsLogic,
|
||||
private val jwtLogic: JwtLogic,
|
||||
private val environment: Environment,
|
||||
protected val securityProperties: CreSecurityProperties
|
||||
) : WebSecurityConfigurerAdapter() {
|
||||
|
@ -70,7 +69,7 @@ abstract class BaseSecurityConfig(
|
|||
}
|
||||
|
||||
override fun configure(authBuilder: AuthenticationManagerBuilder) {
|
||||
authBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder)
|
||||
authBuilder.userDetailsService(userDetailsLogic).passwordEncoder(passwordEncoder)
|
||||
}
|
||||
|
||||
override fun configure(http: HttpSecurity) {
|
||||
|
@ -81,13 +80,13 @@ abstract class BaseSecurityConfig(
|
|||
.addFilter(
|
||||
JwtAuthenticationFilter(
|
||||
authenticationManager(),
|
||||
jwtService,
|
||||
jwtLogic,
|
||||
securityProperties,
|
||||
this::updateUserLoginTime
|
||||
)
|
||||
)
|
||||
.addFilter(
|
||||
JwtAuthorizationFilter(jwtService, authenticationManager(), userDetailsService)
|
||||
JwtAuthorizationFilter(jwtLogic, authenticationManager(), userDetailsLogic)
|
||||
)
|
||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
.and()
|
||||
|
@ -118,12 +117,12 @@ abstract class BaseSecurityConfig(
|
|||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
@EnableConfigurationProperties(CreSecurityProperties::class)
|
||||
class SecurityConfig(
|
||||
@Lazy userDetailsService: UserDetailsService,
|
||||
@Lazy private val userService: UserService,
|
||||
jwtService: JwtService,
|
||||
@Lazy userDetailsLogic: UserDetailsLogic,
|
||||
@Lazy private val userLogic: UserLogic,
|
||||
jwtLogic: JwtLogic,
|
||||
environment: Environment,
|
||||
securityProperties: CreSecurityProperties
|
||||
) : BaseSecurityConfig(userDetailsService, jwtService, environment, securityProperties) {
|
||||
) : BaseSecurityConfig(userDetailsLogic, jwtLogic, environment, securityProperties) {
|
||||
override val logger = KotlinLogging.logger {}
|
||||
|
||||
@PostConstruct
|
||||
|
@ -137,7 +136,7 @@ class SecurityConfig(
|
|||
}
|
||||
|
||||
override fun updateUserLoginTime(userId: Long) {
|
||||
userService.updateLastLoginTime(userId)
|
||||
userLogic.updateLastLoginTime(userId)
|
||||
}
|
||||
|
||||
private fun createRootUser() {
|
||||
|
@ -146,8 +145,8 @@ class SecurityConfig(
|
|||
}
|
||||
|
||||
with(securityProperties.root!!) {
|
||||
if (!userService.existsById(this.id)) {
|
||||
userService.save(
|
||||
if (!userLogic.existsById(this.id)) {
|
||||
userLogic.save(
|
||||
User(
|
||||
id = this.id,
|
||||
firstName = rootUserFirstName,
|
||||
|
@ -166,11 +165,11 @@ class SecurityConfig(
|
|||
@Profile("emergency")
|
||||
@EnableConfigurationProperties(CreSecurityProperties::class)
|
||||
class EmergencySecurityConfig(
|
||||
userDetailsService: UserDetailsService,
|
||||
jwtService: JwtService,
|
||||
userDetailsLogic: UserDetailsLogic,
|
||||
jwtLogic: JwtLogic,
|
||||
environment: Environment,
|
||||
securityProperties: CreSecurityProperties
|
||||
) : BaseSecurityConfig(userDetailsService, jwtService, environment, securityProperties) {
|
||||
) : BaseSecurityConfig(userDetailsLogic, jwtLogic, environment, securityProperties) {
|
||||
override val logger = KotlinLogging.logger {}
|
||||
|
||||
init {
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.repository.CompanyRepository
|
||||
import org.springframework.context.annotation.Lazy
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
interface CompanyService :
|
||||
interface CompanyLogic :
|
||||
ExternalNamedModelService<Company, CompanySaveDto, CompanyUpdateDto, Company, CompanyRepository> {
|
||||
/** Checks if the given [company] is used by one or more recipes. */
|
||||
fun isLinkedToRecipes(company: Company): Boolean
|
||||
}
|
||||
|
||||
@Service
|
||||
@Profile("!emergency")
|
||||
class CompanyServiceImpl(
|
||||
@RequireDatabase
|
||||
class DefaultCompanyLogic(
|
||||
companyRepository: CompanyRepository,
|
||||
@Lazy val recipeService: RecipeService
|
||||
@Lazy val recipeLogic: RecipeLogic
|
||||
) :
|
||||
AbstractExternalNamedModelService<Company, CompanySaveDto, CompanyUpdateDto, Company, CompanyRepository>(
|
||||
companyRepository
|
||||
),
|
||||
CompanyService {
|
||||
CompanyLogic {
|
||||
override fun idNotFoundException(id: Long) = companyIdNotFoundException(id)
|
||||
override fun idAlreadyExistsException(id: Long) = companyIdAlreadyExistsException(id)
|
||||
override fun nameNotFoundException(name: String) = companyNameNotFoundException(name)
|
||||
|
@ -29,7 +29,7 @@ class CompanyServiceImpl(
|
|||
|
||||
override fun Company.toOutput() = this
|
||||
|
||||
override fun isLinkedToRecipes(company: Company): Boolean = recipeService.existsByCompany(company)
|
||||
override fun isLinkedToRecipes(company: Company): Boolean = recipeLogic.existsByCompany(company)
|
||||
|
||||
override fun update(entity: CompanyUpdateDto): Company {
|
||||
// Lazy loaded to prevent checking the database when not necessary
|
|
@ -1,14 +1,14 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.exception.RestException
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.utils.mapMayThrow
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.stereotype.Service
|
||||
import javax.transaction.Transactional
|
||||
|
||||
interface InventoryService {
|
||||
interface InventoryLogic {
|
||||
/** Adds each given [MaterialQuantityDto] to the inventory and returns the updated quantities. */
|
||||
fun add(materialQuantities: Collection<MaterialQuantityDto>): Collection<MaterialQuantityDto>
|
||||
|
||||
|
@ -26,11 +26,11 @@ interface InventoryService {
|
|||
}
|
||||
|
||||
@Service
|
||||
@Profile("!emergency")
|
||||
class InventoryServiceImpl(
|
||||
private val materialService: MaterialService,
|
||||
private val mixService: MixService
|
||||
) : InventoryService {
|
||||
@RequireDatabase
|
||||
class DefaultInventoryLogic(
|
||||
private val materialLogic: MaterialLogic,
|
||||
private val mixLogic: MixLogic
|
||||
) : InventoryLogic {
|
||||
@Transactional
|
||||
override fun add(materialQuantities: Collection<MaterialQuantityDto>) =
|
||||
materialQuantities.map {
|
||||
|
@ -38,14 +38,14 @@ class InventoryServiceImpl(
|
|||
}
|
||||
|
||||
override fun add(materialQuantity: MaterialQuantityDto) =
|
||||
materialService.updateQuantity(
|
||||
materialService.getById(materialQuantity.material),
|
||||
materialLogic.updateQuantity(
|
||||
materialLogic.getById(materialQuantity.material),
|
||||
materialQuantity.quantity
|
||||
)
|
||||
|
||||
@Transactional
|
||||
override fun deductMix(mixRatio: MixDeductDto): Collection<MaterialQuantityDto> {
|
||||
val mix = mixService.getById(mixRatio.id)
|
||||
val mix = mixLogic.getById(mixRatio.id)
|
||||
val firstMixMaterial = mix.mixMaterials.first()
|
||||
val adjustedFirstMaterialQuantity = firstMixMaterial.quantity * mixRatio.ratio
|
||||
|
||||
|
@ -80,9 +80,9 @@ class InventoryServiceImpl(
|
|||
}
|
||||
|
||||
override fun deduct(materialQuantity: MaterialQuantityDto): Float =
|
||||
with(materialService.getById(materialQuantity.material)) {
|
||||
with(materialLogic.getById(materialQuantity.material)) {
|
||||
if (this.inventoryQuantity >= materialQuantity.quantity) {
|
||||
materialService.updateQuantity(this, -materialQuantity.quantity)
|
||||
materialLogic.updateQuantity(this, -materialQuantity.quantity)
|
||||
} else {
|
||||
throw NotEnoughInventoryException(materialQuantity.quantity, this)
|
||||
}
|
|
@ -1,18 +1,18 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.logic.config.ConfigurationLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.WriteableFileLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.repository.MaterialRepository
|
||||
import dev.fyloz.colorrecipesexplorer.rest.FILE_CONTROLLER_PATH
|
||||
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.WriteableFileService
|
||||
import io.jsonwebtoken.lang.Assert
|
||||
import org.springframework.context.annotation.Lazy
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.stereotype.Service
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
interface MaterialService :
|
||||
interface MaterialLogic :
|
||||
ExternalNamedModelService<Material, MaterialSaveDto, MaterialUpdateDto, MaterialOutputDto, MaterialRepository> {
|
||||
/** Checks if a material with the given [materialType] exists. */
|
||||
fun existsByMaterialType(materialType: MaterialType): Boolean
|
||||
|
@ -34,19 +34,19 @@ interface MaterialService :
|
|||
}
|
||||
|
||||
@Service
|
||||
@Profile("!emergency")
|
||||
class MaterialServiceImpl(
|
||||
@RequireDatabase
|
||||
class DefaultMaterialLogic(
|
||||
materialRepository: MaterialRepository,
|
||||
val recipeService: RecipeService,
|
||||
val mixService: MixService,
|
||||
@Lazy val materialTypeService: MaterialTypeService,
|
||||
val fileService: WriteableFileService,
|
||||
val configService: ConfigurationService
|
||||
val recipeLogic: RecipeLogic,
|
||||
val mixLogic: MixLogic,
|
||||
@Lazy val materialTypeLogic: MaterialTypeLogic,
|
||||
val fileService: WriteableFileLogic,
|
||||
val configService: ConfigurationLogic
|
||||
) :
|
||||
AbstractExternalNamedModelService<Material, MaterialSaveDto, MaterialUpdateDto, MaterialOutputDto, MaterialRepository>(
|
||||
materialRepository
|
||||
),
|
||||
MaterialService {
|
||||
MaterialLogic {
|
||||
override fun idNotFoundException(id: Long) = materialIdNotFoundException(id)
|
||||
override fun idAlreadyExistsException(id: Long) = materialIdAlreadyExistsException(id)
|
||||
override fun nameNotFoundException(name: String) = materialNameNotFoundException(name)
|
||||
|
@ -80,7 +80,7 @@ class MaterialServiceImpl(
|
|||
material(
|
||||
name = entity.name,
|
||||
inventoryQuantity = entity.inventoryQuantity,
|
||||
materialType = materialTypeService.getById(materialTypeId),
|
||||
materialType = materialTypeLogic.getById(materialTypeId),
|
||||
isMixType = false
|
||||
)
|
||||
}).apply {
|
||||
|
@ -102,7 +102,7 @@ class MaterialServiceImpl(
|
|||
name = if (name != null && name.isNotBlank()) name else persistedMaterial.name,
|
||||
inventoryQuantity = if (inventoryQuantity != null && inventoryQuantity != Float.MIN_VALUE) inventoryQuantity else persistedMaterial.inventoryQuantity,
|
||||
isMixType = persistedMaterial.isMixType,
|
||||
materialType = if (materialTypeId != null) materialTypeService.getById(materialTypeId) else persistedMaterial.materialType
|
||||
materialType = if (materialTypeId != null) materialTypeLogic.getById(materialTypeId) else persistedMaterial.materialType
|
||||
)
|
||||
}).apply {
|
||||
if (entity.simdutFile != null && !entity.simdutFile.isEmpty) fileService.write(
|
||||
|
@ -120,13 +120,13 @@ class MaterialServiceImpl(
|
|||
}
|
||||
|
||||
override fun getAllForMixCreation(recipeId: Long): Collection<MaterialOutputDto> {
|
||||
val recipesMixTypes = recipeService.getById(recipeId).mixTypes
|
||||
val recipesMixTypes = recipeLogic.getById(recipeId).mixTypes
|
||||
return getAllForOutput()
|
||||
.filter { !it.isMixType || recipesMixTypes.any { mixType -> mixType.material.id == it.id } }
|
||||
}
|
||||
|
||||
override fun getAllForMixUpdate(mixId: Long): Collection<MaterialOutputDto> {
|
||||
val mix = mixService.getById(mixId)
|
||||
val mix = mixLogic.getById(mixId)
|
||||
val recipesMixTypes = mix.recipe.mixTypes
|
||||
return getAllForOutput()
|
||||
.filter { !it.isMixType || recipesMixTypes.any { mixType -> mixType.material.id == it.id } }
|
|
@ -1,12 +1,12 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.model.validation.isNotNullAndNotBlank
|
||||
import dev.fyloz.colorrecipesexplorer.repository.MaterialTypeRepository
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
interface MaterialTypeService :
|
||||
interface MaterialTypeLogic :
|
||||
ExternalNamedModelService<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialType, MaterialTypeRepository> {
|
||||
/** Checks if a material type with the given [prefix] exists. */
|
||||
fun existsByPrefix(prefix: String): Boolean
|
||||
|
@ -25,11 +25,11 @@ interface MaterialTypeService :
|
|||
}
|
||||
|
||||
@Service
|
||||
@Profile("!emergency")
|
||||
class MaterialTypeServiceImpl(repository: MaterialTypeRepository, private val materialService: MaterialService) :
|
||||
@RequireDatabase
|
||||
class DefaultMaterialTypeLogic(repository: MaterialTypeRepository, private val materialLogic: MaterialLogic) :
|
||||
AbstractExternalNamedModelService<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialType, MaterialTypeRepository>(
|
||||
repository
|
||||
), MaterialTypeService {
|
||||
), MaterialTypeLogic {
|
||||
override fun idNotFoundException(id: Long) = materialTypeIdNotFoundException(id)
|
||||
override fun idAlreadyExistsException(id: Long) = materialIdAlreadyExistsException(id)
|
||||
override fun nameNotFoundException(name: String) = materialTypeNameNotFoundException(name)
|
||||
|
@ -39,7 +39,7 @@ class MaterialTypeServiceImpl(repository: MaterialTypeRepository, private val ma
|
|||
|
||||
override fun existsByPrefix(prefix: String): Boolean = repository.existsByPrefix(prefix)
|
||||
override fun isUsedByMaterial(materialType: MaterialType): Boolean =
|
||||
materialService.existsByMaterialType(materialType)
|
||||
materialLogic.existsByMaterialType(materialType)
|
||||
|
||||
override fun getAllSystemTypes(): Collection<MaterialType> = repository.findAllBySystemTypeIs(true)
|
||||
override fun getAllNonSystemType(): Collection<MaterialType> = repository.findAllBySystemTypeIs(false)
|
|
@ -1,14 +1,14 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.repository.MixRepository
|
||||
import dev.fyloz.colorrecipesexplorer.utils.setAll
|
||||
import org.springframework.context.annotation.Lazy
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.stereotype.Service
|
||||
import javax.transaction.Transactional
|
||||
|
||||
interface MixService : ExternalModelService<Mix, MixSaveDto, MixUpdateDto, MixOutputDto, MixRepository> {
|
||||
interface MixLogic : ExternalModelService<Mix, MixSaveDto, MixUpdateDto, MixOutputDto, MixRepository> {
|
||||
/** Gets all mixes with the given [mixType]. */
|
||||
fun getAllByMixType(mixType: MixType): Collection<Mix>
|
||||
|
||||
|
@ -23,15 +23,15 @@ interface MixService : ExternalModelService<Mix, MixSaveDto, MixUpdateDto, MixOu
|
|||
}
|
||||
|
||||
@Service
|
||||
@Profile("!emergency")
|
||||
class MixServiceImpl(
|
||||
@RequireDatabase
|
||||
class DefaultMixLogic(
|
||||
mixRepository: MixRepository,
|
||||
@Lazy val recipeService: RecipeService,
|
||||
@Lazy val materialTypeService: MaterialTypeService,
|
||||
val mixMaterialService: MixMaterialService,
|
||||
val mixTypeService: MixTypeService
|
||||
@Lazy val recipeLogic: RecipeLogic,
|
||||
@Lazy val materialTypeLogic: MaterialTypeLogic,
|
||||
val mixMaterialLogic: MixMaterialLogic,
|
||||
val mixTypeLogic: MixTypeLogic
|
||||
) : AbstractExternalModelService<Mix, MixSaveDto, MixUpdateDto, MixOutputDto, MixRepository>(mixRepository),
|
||||
MixService {
|
||||
MixLogic {
|
||||
override fun idNotFoundException(id: Long) = mixIdNotFoundException(id)
|
||||
override fun idAlreadyExistsException(id: Long) = mixIdAlreadyExistsException(id)
|
||||
|
||||
|
@ -43,7 +43,7 @@ class MixServiceImpl(
|
|||
this.location,
|
||||
this.mixType,
|
||||
this.mixMaterials.map {
|
||||
with(mixMaterialService) {
|
||||
with(mixMaterialLogic) {
|
||||
return@with it.toOutput()
|
||||
}
|
||||
}.toSet()
|
||||
|
@ -51,17 +51,17 @@ class MixServiceImpl(
|
|||
|
||||
@Transactional
|
||||
override fun save(entity: MixSaveDto): Mix {
|
||||
val recipe = recipeService.getById(entity.recipeId)
|
||||
val materialType = materialTypeService.getById(entity.materialTypeId)
|
||||
val mixType = mixTypeService.getOrCreateForNameAndMaterialType(entity.name, materialType)
|
||||
val recipe = recipeLogic.getById(entity.recipeId)
|
||||
val materialType = materialTypeLogic.getById(entity.materialTypeId)
|
||||
val mixType = mixTypeLogic.getOrCreateForNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
val mixMaterials = if (entity.mixMaterials != null) mixMaterialService.create(entity.mixMaterials) else setOf()
|
||||
mixMaterialService.validateMixMaterials(mixMaterials)
|
||||
val mixMaterials = if (entity.mixMaterials != null) mixMaterialLogic.create(entity.mixMaterials) else setOf()
|
||||
mixMaterialLogic.validateMixMaterials(mixMaterials)
|
||||
|
||||
var mix = mix(recipe = recipe, mixType = mixType, mixMaterials = mixMaterials.toMutableSet())
|
||||
mix = save(mix)
|
||||
|
||||
recipeService.addMix(recipe, mix)
|
||||
recipeLogic.addMix(recipe, mix)
|
||||
|
||||
return mix
|
||||
}
|
||||
|
@ -72,18 +72,18 @@ class MixServiceImpl(
|
|||
if (entity.name != null || entity.materialTypeId != null) {
|
||||
val name = entity.name ?: mix.mixType.name
|
||||
val materialType = if (entity.materialTypeId != null)
|
||||
materialTypeService.getById(entity.materialTypeId)
|
||||
materialTypeLogic.getById(entity.materialTypeId)
|
||||
else
|
||||
mix.mixType.material.materialType!!
|
||||
|
||||
mix.mixType = if (mixTypeIsShared(mix.mixType)) {
|
||||
mixTypeService.saveForNameAndMaterialType(name, materialType)
|
||||
mixTypeLogic.saveForNameAndMaterialType(name, materialType)
|
||||
} else {
|
||||
mixTypeService.updateForNameAndMaterialType(mix.mixType, name, materialType)
|
||||
mixTypeLogic.updateForNameAndMaterialType(mix.mixType, name, materialType)
|
||||
}
|
||||
}
|
||||
if (entity.mixMaterials != null) {
|
||||
mix.mixMaterials.setAll(mixMaterialService.create(entity.mixMaterials!!).toMutableSet())
|
||||
mix.mixMaterials.setAll(mixMaterialLogic.create(entity.mixMaterials!!).toMutableSet())
|
||||
}
|
||||
return update(mix)
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ class MixServiceImpl(
|
|||
@Transactional
|
||||
override fun delete(entity: Mix) {
|
||||
if (!repository.canBeDeleted(entity.id!!)) throw cannotDeleteMixException(entity)
|
||||
recipeService.removeMix(entity)
|
||||
recipeLogic.removeMix(entity)
|
||||
super.delete(entity)
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.exception.RestException
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
|
@ -10,7 +10,7 @@ import org.springframework.context.annotation.Profile
|
|||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
interface MixMaterialService : ModelService<MixMaterial, MixMaterialRepository> {
|
||||
interface MixMaterialLogic : ModelService<MixMaterial, MixMaterialRepository> {
|
||||
/** Checks if one or more mix materials have the given [material]. */
|
||||
fun existsByMaterial(material: Material): Boolean
|
||||
|
||||
|
@ -35,16 +35,16 @@ interface MixMaterialService : ModelService<MixMaterial, MixMaterialRepository>
|
|||
|
||||
@Service
|
||||
@Profile("!emergency")
|
||||
class MixMaterialServiceImpl(
|
||||
class DefaultMixMaterialLogic(
|
||||
mixMaterialRepository: MixMaterialRepository,
|
||||
@Lazy val materialService: MaterialService
|
||||
) : AbstractModelService<MixMaterial, MixMaterialRepository>(mixMaterialRepository), MixMaterialService {
|
||||
@Lazy val materialLogic: MaterialLogic
|
||||
) : AbstractModelService<MixMaterial, MixMaterialRepository>(mixMaterialRepository), MixMaterialLogic {
|
||||
override fun idNotFoundException(id: Long) = mixMaterialIdNotFoundException(id)
|
||||
override fun idAlreadyExistsException(id: Long) = mixMaterialIdAlreadyExistsException(id)
|
||||
|
||||
override fun MixMaterial.toOutput() = MixMaterialOutputDto(
|
||||
this.id!!,
|
||||
with(materialService) { this@toOutput.material.toOutput() },
|
||||
with(materialLogic) { this@toOutput.material.toOutput() },
|
||||
this.quantity,
|
||||
this.position
|
||||
)
|
||||
|
@ -55,7 +55,7 @@ class MixMaterialServiceImpl(
|
|||
|
||||
override fun create(mixMaterial: MixMaterialDto): MixMaterial =
|
||||
mixMaterial(
|
||||
material = materialService.getById(mixMaterial.materialId),
|
||||
material = materialLogic.getById(mixMaterial.materialId),
|
||||
quantity = mixMaterial.quantity,
|
||||
position = mixMaterial.position
|
||||
)
|
|
@ -1,12 +1,12 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.repository.MixTypeRepository
|
||||
import org.springframework.context.annotation.Lazy
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
interface MixTypeService : NamedModelService<MixType, MixTypeRepository> {
|
||||
interface MixTypeLogic : NamedModelService<MixType, MixTypeRepository> {
|
||||
/** Checks if a [MixType] with the given [name] and [materialType] exists. */
|
||||
fun existsByNameAndMaterialType(name: String, materialType: MaterialType): Boolean
|
||||
|
||||
|
@ -27,13 +27,12 @@ interface MixTypeService : NamedModelService<MixType, MixTypeRepository> {
|
|||
}
|
||||
|
||||
@Service
|
||||
@Profile("!emergency")
|
||||
class MixTypeServiceImpl(
|
||||
mixTypeRepository: MixTypeRepository,
|
||||
@Lazy val materialService: MaterialService,
|
||||
@Lazy val mixService: MixService
|
||||
@RequireDatabase
|
||||
class DefaultMixTypeLogic(
|
||||
mixTypeRepository: MixTypeRepository,
|
||||
@Lazy val materialLogic: MaterialLogic
|
||||
) :
|
||||
AbstractNamedModelService<MixType, MixTypeRepository>(mixTypeRepository), MixTypeService {
|
||||
AbstractNamedModelService<MixType, MixTypeRepository>(mixTypeRepository), MixTypeLogic {
|
||||
override fun idNotFoundException(id: Long) = mixTypeIdNotFoundException(id)
|
||||
override fun idAlreadyExistsException(id: Long) = mixTypeIdAlreadyExistsException(id)
|
||||
override fun nameNotFoundException(name: String) = mixTypeNameNotFoundException(name)
|
||||
|
@ -56,7 +55,7 @@ class MixTypeServiceImpl(
|
|||
saveForNameAndMaterialType(name, materialType)
|
||||
|
||||
override fun save(entity: MixType): MixType {
|
||||
if (materialService.existsByName(entity.name))
|
||||
if (materialLogic.existsByName(entity.name))
|
||||
throw materialNameAlreadyExistsException(entity.name)
|
||||
return super.save(entity)
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.logic.config.ConfigurationLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.WriteableFileLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.users.GroupLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.Group
|
||||
import dev.fyloz.colorrecipesexplorer.model.validation.or
|
||||
import dev.fyloz.colorrecipesexplorer.repository.RecipeRepository
|
||||
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.WriteableFileService
|
||||
import dev.fyloz.colorrecipesexplorer.service.users.GroupService
|
||||
import dev.fyloz.colorrecipesexplorer.utils.setAll
|
||||
import org.springframework.context.annotation.Lazy
|
||||
import org.springframework.stereotype.Service
|
||||
|
@ -16,7 +16,7 @@ import java.time.LocalDate
|
|||
import java.time.Period
|
||||
import javax.transaction.Transactional
|
||||
|
||||
interface RecipeService :
|
||||
interface RecipeLogic :
|
||||
ExternalModelService<Recipe, RecipeSaveDto, RecipeUpdateDto, RecipeOutputDto, RecipeRepository> {
|
||||
/** Checks if one or more recipes have the given [company]. */
|
||||
fun existsByCompany(company: Company): Boolean
|
||||
|
@ -45,19 +45,19 @@ interface RecipeService :
|
|||
|
||||
@Service
|
||||
@RequireDatabase
|
||||
class RecipeServiceImpl(
|
||||
class DefaultRecipeLogic(
|
||||
recipeRepository: RecipeRepository,
|
||||
val companyService: CompanyService,
|
||||
val mixService: MixService,
|
||||
val recipeStepService: RecipeStepService,
|
||||
@Lazy val groupService: GroupService,
|
||||
val recipeImageService: RecipeImageService,
|
||||
val configService: ConfigurationService
|
||||
val companyLogic: CompanyLogic,
|
||||
val mixLogic: MixLogic,
|
||||
val recipeStepLogic: RecipeStepLogic,
|
||||
@Lazy val groupLogic: GroupLogic,
|
||||
val recipeImageLogic: RecipeImageLogic,
|
||||
val configService: ConfigurationLogic
|
||||
) :
|
||||
AbstractExternalModelService<Recipe, RecipeSaveDto, RecipeUpdateDto, RecipeOutputDto, RecipeRepository>(
|
||||
recipeRepository
|
||||
),
|
||||
RecipeService {
|
||||
RecipeLogic {
|
||||
override fun idNotFoundException(id: Long) = recipeIdNotFoundException(id)
|
||||
override fun idAlreadyExistsException(id: Long) = recipeIdAlreadyExistsException(id)
|
||||
|
||||
|
@ -73,12 +73,12 @@ class RecipeServiceImpl(
|
|||
this.remark,
|
||||
this.company,
|
||||
this.mixes.map {
|
||||
with(mixService) {
|
||||
with(mixLogic) {
|
||||
it.toOutput()
|
||||
}
|
||||
}.toSet(),
|
||||
this.groupsInformation,
|
||||
recipeImageService.getAllImages(this)
|
||||
recipeImageLogic.getAllImages(this)
|
||||
.map { this.imageUrl(configService.getContent(ConfigurationType.INSTANCE_URL), it) }
|
||||
.toSet()
|
||||
)
|
||||
|
@ -96,7 +96,7 @@ class RecipeServiceImpl(
|
|||
override fun getAllByCompany(company: Company) = repository.findAllByCompany(company)
|
||||
|
||||
override fun save(entity: RecipeSaveDto): Recipe {
|
||||
val company = companyService.getById(entity.companyId)
|
||||
val company = companyLogic.getById(entity.companyId)
|
||||
|
||||
if (existsByNameAndCompany(entity.name, company)) {
|
||||
throw recipeNameAlreadyExistsForCompanyException(entity.name, company)
|
||||
|
@ -160,12 +160,12 @@ class RecipeServiceImpl(
|
|||
this.steps = it.steps.toMutableSet()
|
||||
}
|
||||
} ?: recipeGroupInformation(
|
||||
group = groupService.getById(it.groupId),
|
||||
group = groupLogic.getById(it.groupId),
|
||||
steps = it.steps.toMutableSet()
|
||||
)
|
||||
|
||||
updatedGroupsInformation.add(updatedGroupInformation)
|
||||
recipeStepService.validateGroupInformationSteps(updatedGroupInformation)
|
||||
recipeStepLogic.validateGroupInformationSteps(updatedGroupInformation)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ class RecipeServiceImpl(
|
|||
}
|
||||
|
||||
if (publicDataDto.mixesLocation != null) {
|
||||
mixService.updateLocations(publicDataDto.mixesLocation)
|
||||
mixLogic.updateLocations(publicDataDto.mixesLocation)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ class RecipeServiceImpl(
|
|||
update(mix.recipe.apply { mixes.remove(mix) })
|
||||
}
|
||||
|
||||
interface RecipeImageService {
|
||||
interface RecipeImageLogic {
|
||||
/** Gets the name of every images associated to the recipe with the given [recipe]. */
|
||||
fun getAllImages(recipe: Recipe): Set<String>
|
||||
|
||||
|
@ -219,9 +219,9 @@ const val RECIPE_IMAGE_EXTENSION = ".jpg"
|
|||
|
||||
@Service
|
||||
@RequireDatabase
|
||||
class RecipeImageServiceImpl(
|
||||
val fileService: WriteableFileService
|
||||
) : RecipeImageService {
|
||||
class DefaultRecipeImageLogic(
|
||||
val fileService: WriteableFileLogic
|
||||
) : RecipeImageLogic {
|
||||
override fun getAllImages(recipe: Recipe) =
|
||||
fileService.listDirectoryFiles(recipe.imagesDirectoryPath)
|
||||
.map { it.name }
|
|
@ -1,16 +1,19 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.exception.RestException
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.model.RecipeGroupInformation
|
||||
import dev.fyloz.colorrecipesexplorer.model.RecipeStep
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.Group
|
||||
import dev.fyloz.colorrecipesexplorer.model.recipeStepIdAlreadyExistsException
|
||||
import dev.fyloz.colorrecipesexplorer.model.recipeStepIdNotFoundException
|
||||
import dev.fyloz.colorrecipesexplorer.repository.RecipeStepRepository
|
||||
import dev.fyloz.colorrecipesexplorer.utils.findDuplicated
|
||||
import dev.fyloz.colorrecipesexplorer.utils.hasGaps
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
interface RecipeStepService : ModelService<RecipeStep, RecipeStepRepository> {
|
||||
interface RecipeStepLogic : ModelService<RecipeStep, RecipeStepRepository> {
|
||||
/** Validates the steps of the given [groupInformation], according to the criteria of [validateSteps]. */
|
||||
fun validateGroupInformationSteps(groupInformation: RecipeGroupInformation)
|
||||
|
||||
|
@ -23,10 +26,10 @@ interface RecipeStepService : ModelService<RecipeStep, RecipeStepRepository> {
|
|||
}
|
||||
|
||||
@Service
|
||||
@Profile("!emergency")
|
||||
class RecipeStepServiceImpl(recipeStepRepository: RecipeStepRepository) :
|
||||
@RequireDatabase
|
||||
class DefaultRecipeStepLogic(recipeStepRepository: RecipeStepRepository) :
|
||||
AbstractModelService<RecipeStep, RecipeStepRepository>(recipeStepRepository),
|
||||
RecipeStepService {
|
||||
RecipeStepLogic {
|
||||
override fun idNotFoundException(id: Long) = recipeStepIdNotFoundException(id)
|
||||
override fun idAlreadyExistsException(id: Long) = recipeStepIdAlreadyExistsException(id)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
||||
import dev.fyloz.colorrecipesexplorer.exception.NotFoundException
|
|
@ -1,14 +1,13 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.logic.config.ConfigurationLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.WriteableFileLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.ConfigurationType
|
||||
import dev.fyloz.colorrecipesexplorer.model.touchupkit.*
|
||||
import dev.fyloz.colorrecipesexplorer.repository.TouchUpKitRepository
|
||||
import dev.fyloz.colorrecipesexplorer.rest.TOUCH_UP_KIT_CONTROLLER_PATH
|
||||
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.FileService
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.WriteableFileService
|
||||
import dev.fyloz.colorrecipesexplorer.utils.*
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.core.io.ByteArrayResource
|
||||
import org.springframework.core.io.Resource
|
||||
import org.springframework.stereotype.Service
|
||||
|
@ -20,7 +19,7 @@ private const val TOUCH_UP_KIT_FILES_PATH = "pdf/touchupkits"
|
|||
const val TOUCH_UP_TEXT_FR = "KIT DE RETOUCHE"
|
||||
const val TOUCH_UP_TEXT_EN = "TOUCH UP KIT"
|
||||
|
||||
interface TouchUpKitService :
|
||||
interface TouchUpKitLogic :
|
||||
ExternalModelService<TouchUpKit, TouchUpKitSaveDto, TouchUpKitUpdateDto, TouchUpKitOutputDto, TouchUpKitRepository> {
|
||||
fun isExpired(touchUpKit: TouchUpKit): Boolean
|
||||
|
||||
|
@ -42,14 +41,14 @@ interface TouchUpKitService :
|
|||
}
|
||||
|
||||
@Service
|
||||
@Profile("!emergency")
|
||||
class TouchUpKitServiceImpl(
|
||||
private val fileService: WriteableFileService,
|
||||
private val configService: ConfigurationService,
|
||||
@RequireDatabase
|
||||
class DefaultTouchUpKitLogic(
|
||||
private val fileService: WriteableFileLogic,
|
||||
private val configService: ConfigurationLogic,
|
||||
touchUpKitRepository: TouchUpKitRepository
|
||||
) : AbstractExternalModelService<TouchUpKit, TouchUpKitSaveDto, TouchUpKitUpdateDto, TouchUpKitOutputDto, TouchUpKitRepository>(
|
||||
touchUpKitRepository
|
||||
), TouchUpKitService {
|
||||
), TouchUpKitLogic {
|
||||
private val cacheGeneratedFiles by lazy {
|
||||
configService.getContent(ConfigurationType.TOUCH_UP_KIT_CACHE_PDF) == true.toString()
|
||||
}
|
|
@ -1,19 +1,19 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.config
|
||||
package dev.fyloz.colorrecipesexplorer.logic.config
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.ResourceFileLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.WriteableFileLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.ResourceFileService
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.WriteableFileService
|
||||
import dev.fyloz.colorrecipesexplorer.utils.decrypt
|
||||
import dev.fyloz.colorrecipesexplorer.utils.encrypt
|
||||
import org.slf4j.Logger
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.context.annotation.Lazy
|
||||
import org.springframework.core.io.Resource
|
||||
import org.springframework.security.crypto.keygen.KeyGenerators
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
|
||||
interface ConfigurationService {
|
||||
interface ConfigurationLogic {
|
||||
/** Gets all set configurations. */
|
||||
fun getAll(): List<ConfigurationBase>
|
||||
|
||||
|
@ -73,13 +73,13 @@ const val CONFIGURATION_ICON_FILE_PATH = "images/icon"
|
|||
const val CONFIGURATION_FORMATTED_LIST_DELIMITER = ';'
|
||||
|
||||
@Service("configurationService")
|
||||
class ConfigurationServiceImpl(
|
||||
@Lazy private val fileService: WriteableFileService,
|
||||
private val resourceFileService: ResourceFileService,
|
||||
class DefaultConfigurationLogic(
|
||||
@Lazy private val fileService: WriteableFileLogic,
|
||||
private val resourceFileService: ResourceFileLogic,
|
||||
private val configurationSource: ConfigurationSource,
|
||||
private val securityProperties: CreSecurityProperties,
|
||||
private val logger: Logger
|
||||
) : ConfigurationService {
|
||||
private val securityProperties: CreSecurityProperties
|
||||
) : ConfigurationLogic {
|
||||
private val logger = KotlinLogging.logger { }
|
||||
private val saltConfigurationType = ConfigurationType.GENERATED_ENCRYPTION_SALT
|
||||
private val encryptionSalt by lazy {
|
||||
securityProperties.configSalt ?: getGeneratedSalt()
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.config
|
||||
package dev.fyloz.colorrecipesexplorer.logic.config
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.JavaFile
|
||||
import dev.fyloz.colorrecipesexplorer.SUPPORTED_DATABASE_VERSION
|
||||
|
@ -11,7 +11,7 @@ import dev.fyloz.colorrecipesexplorer.model.configuration
|
|||
import dev.fyloz.colorrecipesexplorer.repository.ConfigurationRepository
|
||||
import dev.fyloz.colorrecipesexplorer.utils.create
|
||||
import dev.fyloz.colorrecipesexplorer.utils.excludeAll
|
||||
import org.slf4j.Logger
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.boot.info.BuildProperties
|
||||
import org.springframework.context.annotation.Lazy
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
|
@ -36,9 +36,9 @@ interface ConfigurationSource {
|
|||
class CompositeConfigurationSource(
|
||||
@Lazy private val configurationRepository: ConfigurationRepository,
|
||||
private val properties: CreProperties,
|
||||
private val buildInfo: BuildProperties,
|
||||
private val logger: Logger
|
||||
private val buildInfo: BuildProperties
|
||||
) : ConfigurationSource {
|
||||
private val logger = KotlinLogging.logger {}
|
||||
private val repository by lazy { RepositoryConfigurationSource(configurationRepository) }
|
||||
private val file by lazy {
|
||||
FileConfigurationSource("${properties.configDirectory}/$CONFIGURATION_FILE_PATH")
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.files
|
||||
package dev.fyloz.colorrecipesexplorer.logic.files
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.JavaFile
|
||||
import dev.fyloz.colorrecipesexplorer.utils.File
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.files
|
||||
package dev.fyloz.colorrecipesexplorer.logic.files
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties
|
||||
import dev.fyloz.colorrecipesexplorer.exception.RestException
|
||||
|
@ -21,7 +21,7 @@ val BANNED_FILE_PATH_SHARDS = setOf(
|
|||
"//"
|
||||
)
|
||||
|
||||
interface FileService {
|
||||
interface FileLogic {
|
||||
/** Checks if the file at the given [path] exists. */
|
||||
fun exists(path: String): Boolean
|
||||
|
||||
|
@ -35,7 +35,7 @@ interface FileService {
|
|||
fun fullPath(path: String): FilePath
|
||||
}
|
||||
|
||||
interface WriteableFileService : FileService {
|
||||
interface WriteableFileLogic : FileLogic {
|
||||
/** Creates a file at the given [path]. */
|
||||
fun create(path: String)
|
||||
|
||||
|
@ -56,10 +56,10 @@ interface WriteableFileService : FileService {
|
|||
}
|
||||
|
||||
@Service
|
||||
class FileServiceImpl(
|
||||
class DefaultFileLogic(
|
||||
private val fileCache: FileCache,
|
||||
private val creProperties: CreProperties
|
||||
) : WriteableFileService {
|
||||
) : WriteableFileLogic {
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
override fun exists(path: String): Boolean {
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.files
|
||||
package dev.fyloz.colorrecipesexplorer.logic.files
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.utils.FilePath
|
||||
import org.springframework.core.io.Resource
|
||||
|
@ -6,9 +6,9 @@ import org.springframework.core.io.ResourceLoader
|
|||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class ResourceFileService(
|
||||
class ResourceFileLogic(
|
||||
private val resourceLoader: ResourceLoader
|
||||
) : FileService {
|
||||
) : FileLogic {
|
||||
override fun exists(path: String) =
|
||||
fullPath(path).resource.exists()
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.jobs
|
||||
package dev.fyloz.colorrecipesexplorer.logic.jobs
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.service.TouchUpKitService
|
||||
import dev.fyloz.colorrecipesexplorer.logic.TouchUpKitLogic
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.scheduling.annotation.Scheduled
|
||||
|
@ -9,7 +9,7 @@ import org.springframework.stereotype.Component
|
|||
@Component
|
||||
@Profile("!emergency")
|
||||
class TouchUpKitRemover(
|
||||
private val touchUpKitService: TouchUpKitService
|
||||
private val touchUpKitLogic: TouchUpKitLogic
|
||||
) {
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
|
@ -20,10 +20,10 @@ class TouchUpKitRemover(
|
|||
}
|
||||
|
||||
private fun removeExpiredKits() {
|
||||
with(touchUpKitService.getAll().filter(touchUpKitService::isExpired)) {
|
||||
with(touchUpKitLogic.getAll().filter(touchUpKitLogic::isExpired)) {
|
||||
this.forEach {
|
||||
logger.debug("Removed expired touch up kit ${it.id} (${it.project} ${it.buggy})")
|
||||
touchUpKitService.delete(it)
|
||||
touchUpKitLogic.delete(it)
|
||||
}
|
||||
logger.info("Removed ${this.size} expired touch up kits")
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.users
|
||||
package dev.fyloz.colorrecipesexplorer.logic.users
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.security.defaultGroupCookieName
|
||||
import dev.fyloz.colorrecipesexplorer.logic.AbstractExternalNamedModelService
|
||||
import dev.fyloz.colorrecipesexplorer.logic.ExternalNamedModelService
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.*
|
||||
import dev.fyloz.colorrecipesexplorer.repository.GroupRepository
|
||||
import dev.fyloz.colorrecipesexplorer.service.AbstractExternalNamedModelService
|
||||
import dev.fyloz.colorrecipesexplorer.service.ExternalNamedModelService
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.web.util.WebUtils
|
||||
|
@ -14,7 +14,7 @@ import javax.transaction.Transactional
|
|||
|
||||
const val defaultGroupCookieMaxAge = 10 * 365 * 24 * 60 * 60 // 10 ans
|
||||
|
||||
interface GroupService :
|
||||
interface GroupLogic :
|
||||
ExternalNamedModelService<Group, GroupSaveDto, GroupUpdateDto, GroupOutputDto, GroupRepository> {
|
||||
/** Gets all the users of the group with the given [id]. */
|
||||
fun getUsersForGroup(id: Long): Collection<User>
|
||||
|
@ -28,13 +28,13 @@ interface GroupService :
|
|||
|
||||
@Service
|
||||
@Profile("!emergency")
|
||||
class GroupServiceImpl(
|
||||
private val userService: UserService,
|
||||
class DefaultGroupLogic(
|
||||
private val userLogic: UserLogic,
|
||||
groupRepository: GroupRepository
|
||||
) : AbstractExternalNamedModelService<Group, GroupSaveDto, GroupUpdateDto, GroupOutputDto, GroupRepository>(
|
||||
groupRepository
|
||||
),
|
||||
GroupService {
|
||||
GroupLogic {
|
||||
override fun idNotFoundException(id: Long) = groupIdNotFoundException(id)
|
||||
override fun idAlreadyExistsException(id: Long) = groupIdAlreadyExistsException(id)
|
||||
override fun nameNotFoundException(name: String) = groupNameNotFoundException(name)
|
||||
|
@ -49,12 +49,12 @@ class GroupServiceImpl(
|
|||
|
||||
override fun existsByName(name: String): Boolean = repository.existsByName(name)
|
||||
override fun getUsersForGroup(id: Long): Collection<User> =
|
||||
userService.getByGroup(getById(id))
|
||||
userLogic.getByGroup(getById(id))
|
||||
|
||||
@Transactional
|
||||
override fun save(entity: Group): Group {
|
||||
return super<AbstractExternalNamedModelService>.save(entity).apply {
|
||||
userService.saveDefaultGroupUser(this)
|
||||
userLogic.saveDefaultGroupUser(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,14 +71,14 @@ class GroupServiceImpl(
|
|||
|
||||
@Transactional
|
||||
override fun delete(entity: Group) {
|
||||
userService.delete(userService.getDefaultGroupUser(entity))
|
||||
userLogic.delete(userLogic.getDefaultGroupUser(entity))
|
||||
super.delete(entity)
|
||||
}
|
||||
|
||||
override fun getRequestDefaultGroup(request: HttpServletRequest): Group {
|
||||
val defaultGroupCookie = WebUtils.getCookie(request, defaultGroupCookieName)
|
||||
?: throw NoDefaultGroupException()
|
||||
val defaultGroupUser = userService.getById(
|
||||
val defaultGroupUser = userLogic.getById(
|
||||
defaultGroupCookie.value.toLong(),
|
||||
ignoreDefaultGroupUsers = false,
|
||||
ignoreSystemUsers = true
|
||||
|
@ -88,7 +88,7 @@ class GroupServiceImpl(
|
|||
|
||||
override fun setResponseDefaultGroup(groupId: Long, response: HttpServletResponse) {
|
||||
val group = getById(groupId)
|
||||
val defaultGroupUser = userService.getDefaultGroupUser(group)
|
||||
val defaultGroupUser = userLogic.getDefaultGroupUser(group)
|
||||
response.addHeader(
|
||||
"Set-Cookie",
|
||||
"$defaultGroupCookieName=${defaultGroupUser.id}; Max-Age=$defaultGroupCookieMaxAge; Path=/api; HttpOnly; Secure; SameSite=strict"
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.users
|
||||
package dev.fyloz.colorrecipesexplorer.logic.users
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
|
@ -18,7 +18,7 @@ import java.util.*
|
|||
|
||||
const val jwtClaimUser = "user"
|
||||
|
||||
interface JwtService {
|
||||
interface JwtLogic {
|
||||
/** Build a JWT token for the given [userDetails]. */
|
||||
fun buildJwt(userDetails: UserDetails): String
|
||||
|
||||
|
@ -30,10 +30,10 @@ interface JwtService {
|
|||
}
|
||||
|
||||
@Service
|
||||
class JwtServiceImpl(
|
||||
class DefaultJwtLogic(
|
||||
val objectMapper: ObjectMapper,
|
||||
val securityProperties: CreSecurityProperties
|
||||
) : JwtService {
|
||||
) : JwtLogic {
|
||||
private val secretKey by lazy {
|
||||
securityProperties.jwtSecret.base64encode()
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.users
|
||||
package dev.fyloz.colorrecipesexplorer.logic.users
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.SpringUserDetails
|
||||
import dev.fyloz.colorrecipesexplorer.SpringUserDetailsService
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties
|
||||
import dev.fyloz.colorrecipesexplorer.exception.NotFoundException
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.Permission
|
||||
|
@ -12,16 +13,16 @@ import org.springframework.context.annotation.Profile
|
|||
import org.springframework.security.core.userdetails.UsernameNotFoundException
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
interface UserDetailsService : SpringUserDetailsService {
|
||||
interface UserDetailsLogic : SpringUserDetailsService {
|
||||
/** Loads an [User] for the given [id]. */
|
||||
fun loadUserById(id: Long, ignoreDefaultGroupUsers: Boolean = false): UserDetails
|
||||
}
|
||||
|
||||
@Service
|
||||
@Profile("!emergency")
|
||||
class UserDetailsServiceImpl(
|
||||
private val userService: UserService
|
||||
) : UserDetailsService {
|
||||
@RequireDatabase
|
||||
class DefaultUserDetailsLogic(
|
||||
private val userLogic: UserLogic
|
||||
) : UserDetailsLogic {
|
||||
override fun loadUserByUsername(username: String): UserDetails {
|
||||
try {
|
||||
return loadUserById(username.toLong(), true)
|
||||
|
@ -31,7 +32,7 @@ class UserDetailsServiceImpl(
|
|||
}
|
||||
|
||||
override fun loadUserById(id: Long, ignoreDefaultGroupUsers: Boolean): UserDetails {
|
||||
val user = userService.getById(
|
||||
val user = userLogic.getById(
|
||||
id,
|
||||
ignoreDefaultGroupUsers = ignoreDefaultGroupUsers,
|
||||
ignoreSystemUsers = false
|
||||
|
@ -42,9 +43,9 @@ class UserDetailsServiceImpl(
|
|||
|
||||
@Service
|
||||
@Profile("emergency")
|
||||
class EmergencyUserDetailsServiceImpl(
|
||||
class EmergencyUserDetailsLogic(
|
||||
securityProperties: CreSecurityProperties
|
||||
) : UserDetailsService {
|
||||
) : UserDetailsLogic {
|
||||
private val users: Set<User>
|
||||
|
||||
init {
|
|
@ -1,20 +1,19 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.users
|
||||
package dev.fyloz.colorrecipesexplorer.logic.users
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.security.blacklistedJwtTokens
|
||||
import dev.fyloz.colorrecipesexplorer.logic.AbstractExternalModelService
|
||||
import dev.fyloz.colorrecipesexplorer.logic.ExternalModelService
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.*
|
||||
import dev.fyloz.colorrecipesexplorer.model.validation.or
|
||||
import dev.fyloz.colorrecipesexplorer.repository.UserRepository
|
||||
import dev.fyloz.colorrecipesexplorer.service.AbstractExternalModelService
|
||||
import dev.fyloz.colorrecipesexplorer.service.ExternalModelService
|
||||
import org.springframework.context.annotation.Lazy
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.web.util.WebUtils
|
||||
import java.time.LocalDateTime
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
|
||||
interface UserService :
|
||||
interface UserLogic :
|
||||
ExternalModelService<User, UserSaveDto, UserUpdateDto, UserOutputDto, UserRepository> {
|
||||
/** Check if an [User] with the given [firstName] and [lastName] exists. */
|
||||
fun existsByFirstNameAndLastName(firstName: String, lastName: String): Boolean
|
||||
|
@ -52,13 +51,13 @@ interface UserService :
|
|||
|
||||
@Service
|
||||
@Profile("!emergency")
|
||||
class UserServiceImpl(
|
||||
class DefaultUserLogic(
|
||||
userRepository: UserRepository,
|
||||
@Lazy val groupService: GroupService,
|
||||
@Lazy val groupLogic: GroupLogic,
|
||||
) : AbstractExternalModelService<User, UserSaveDto, UserUpdateDto, UserOutputDto, UserRepository>(
|
||||
userRepository
|
||||
),
|
||||
UserService {
|
||||
UserLogic {
|
||||
override fun idNotFoundException(id: Long) = userIdNotFoundException(id)
|
||||
override fun idAlreadyExistsException(id: Long) = userIdAlreadyExistsException(id)
|
||||
|
||||
|
@ -96,7 +95,7 @@ class UserServiceImpl(
|
|||
plainPassword = password,
|
||||
isDefaultGroupUser = false,
|
||||
isSystemUser = false,
|
||||
group = if (groupId != null) groupService.getById(groupId) else null,
|
||||
group = if (groupId != null) groupLogic.getById(groupId) else null,
|
||||
permissions = permissions
|
||||
)
|
||||
})
|
||||
|
@ -142,7 +141,7 @@ class UserServiceImpl(
|
|||
password = persistedUser.password,
|
||||
isDefaultGroupUser = false,
|
||||
isSystemUser = false,
|
||||
group = if (entity.groupId != null) groupService.getById(entity.groupId) else persistedUser.group,
|
||||
group = if (entity.groupId != null) groupLogic.getById(entity.groupId) else persistedUser.group,
|
||||
permissions = permissions?.toMutableSet() ?: persistedUser.permissions,
|
||||
lastLoginTime = persistedUser.lastLoginTime
|
||||
)
|
|
@ -2,10 +2,9 @@ package dev.fyloz.colorrecipesexplorer.rest
|
|||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeEditUsers
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeViewUsers
|
||||
import dev.fyloz.colorrecipesexplorer.logic.users.GroupLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.users.UserLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.*
|
||||
import dev.fyloz.colorrecipesexplorer.service.users.GroupService
|
||||
import dev.fyloz.colorrecipesexplorer.service.users.UserService
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
|
@ -20,22 +19,22 @@ private const val GROUP_CONTROLLER_PATH = "api/user/group"
|
|||
@RestController
|
||||
@RequestMapping(USER_CONTROLLER_PATH)
|
||||
@Profile("!emergency")
|
||||
class UserController(private val userService: UserService) {
|
||||
class UserController(private val userLogic: UserLogic) {
|
||||
@GetMapping
|
||||
@PreAuthorizeViewUsers
|
||||
fun getAll() =
|
||||
ok(userService.getAllForOutput())
|
||||
ok(userLogic.getAllForOutput())
|
||||
|
||||
@GetMapping("{id}")
|
||||
@PreAuthorizeViewUsers
|
||||
fun getById(@PathVariable id: Long) =
|
||||
ok(userService.getByIdForOutput(id))
|
||||
ok(userLogic.getByIdForOutput(id))
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorizeEditUsers
|
||||
fun save(@Valid @RequestBody user: UserSaveDto) =
|
||||
created<UserOutputDto>(USER_CONTROLLER_PATH) {
|
||||
with(userService) {
|
||||
with(userLogic) {
|
||||
save(user).toOutput()
|
||||
}
|
||||
}
|
||||
|
@ -44,14 +43,14 @@ class UserController(private val userService: UserService) {
|
|||
@PreAuthorizeEditUsers
|
||||
fun update(@Valid @RequestBody user: UserUpdateDto) =
|
||||
noContent {
|
||||
userService.update(user)
|
||||
userLogic.update(user)
|
||||
}
|
||||
|
||||
@PutMapping("{id}/password", consumes = [MediaType.TEXT_PLAIN_VALUE])
|
||||
@PreAuthorizeEditUsers
|
||||
fun updatePassword(@PathVariable id: Long, @RequestBody password: String) =
|
||||
noContent {
|
||||
userService.updatePassword(id, password)
|
||||
userLogic.updatePassword(id, password)
|
||||
}
|
||||
|
||||
@PutMapping("{userId}/permissions/{permission}")
|
||||
|
@ -60,7 +59,7 @@ class UserController(private val userService: UserService) {
|
|||
@PathVariable userId: Long,
|
||||
@PathVariable permission: Permission
|
||||
) = noContent {
|
||||
userService.addPermission(userId, permission)
|
||||
userLogic.addPermission(userId, permission)
|
||||
}
|
||||
|
||||
@DeleteMapping("{userId}/permissions/{permission}")
|
||||
|
@ -69,37 +68,37 @@ class UserController(private val userService: UserService) {
|
|||
@PathVariable userId: Long,
|
||||
@PathVariable permission: Permission
|
||||
) = noContent {
|
||||
userService.removePermission(userId, permission)
|
||||
userLogic.removePermission(userId, permission)
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@PreAuthorizeEditUsers
|
||||
fun deleteById(@PathVariable id: Long) =
|
||||
userService.deleteById(id)
|
||||
userLogic.deleteById(id)
|
||||
}
|
||||
|
||||
@RestController
|
||||
@RequestMapping(GROUP_CONTROLLER_PATH)
|
||||
@Profile("!emergency")
|
||||
class GroupsController(
|
||||
private val groupService: GroupService,
|
||||
private val userService: UserService
|
||||
private val groupLogic: GroupLogic,
|
||||
private val userLogic: UserLogic
|
||||
) {
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('VIEW_RECIPES', 'VIEW_USERS')")
|
||||
fun getAll() =
|
||||
ok(groupService.getAllForOutput())
|
||||
ok(groupLogic.getAllForOutput())
|
||||
|
||||
@GetMapping("{id}")
|
||||
@PreAuthorizeViewUsers
|
||||
fun getById(@PathVariable id: Long) =
|
||||
ok(groupService.getByIdForOutput(id))
|
||||
ok(groupLogic.getByIdForOutput(id))
|
||||
|
||||
@GetMapping("{id}/users")
|
||||
@PreAuthorizeViewUsers
|
||||
fun getUsersForGroup(@PathVariable id: Long) =
|
||||
ok(with(userService) {
|
||||
groupService.getUsersForGroup(id)
|
||||
ok(with(userLogic) {
|
||||
groupLogic.getUsersForGroup(id)
|
||||
.map { it.toOutput() }
|
||||
})
|
||||
|
||||
|
@ -107,27 +106,27 @@ class GroupsController(
|
|||
@PreAuthorizeViewUsers
|
||||
fun setDefaultGroup(@PathVariable groupId: Long, response: HttpServletResponse) =
|
||||
noContent {
|
||||
groupService.setResponseDefaultGroup(groupId, response)
|
||||
groupLogic.setResponseDefaultGroup(groupId, response)
|
||||
}
|
||||
|
||||
@GetMapping("default")
|
||||
@PreAuthorizeViewUsers
|
||||
fun getRequestDefaultGroup(request: HttpServletRequest) =
|
||||
ok(with(groupService) {
|
||||
ok(with(groupLogic) {
|
||||
getRequestDefaultGroup(request).toOutput()
|
||||
})
|
||||
|
||||
@GetMapping("currentuser")
|
||||
fun getCurrentGroupUser(request: HttpServletRequest) =
|
||||
ok(with(groupService.getRequestDefaultGroup(request)) {
|
||||
userService.getDefaultGroupUser(this).toOutputDto()
|
||||
ok(with(groupLogic.getRequestDefaultGroup(request)) {
|
||||
userLogic.getDefaultGroupUser(this).toOutputDto()
|
||||
})
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorizeEditUsers
|
||||
fun save(@Valid @RequestBody group: GroupSaveDto) =
|
||||
created<GroupOutputDto>(GROUP_CONTROLLER_PATH) {
|
||||
with(groupService) {
|
||||
with(groupLogic) {
|
||||
save(group).toOutput()
|
||||
}
|
||||
}
|
||||
|
@ -136,25 +135,25 @@ class GroupsController(
|
|||
@PreAuthorizeEditUsers
|
||||
fun update(@Valid @RequestBody group: GroupUpdateDto) =
|
||||
noContent {
|
||||
groupService.update(group)
|
||||
groupLogic.update(group)
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@PreAuthorizeEditUsers
|
||||
fun deleteById(@PathVariable id: Long) =
|
||||
noContent {
|
||||
groupService.deleteById(id)
|
||||
groupLogic.deleteById(id)
|
||||
}
|
||||
}
|
||||
|
||||
@RestController
|
||||
@RequestMapping("api")
|
||||
@Profile("!emergency")
|
||||
class LogoutController(private val userService: UserService) {
|
||||
class LogoutController(private val userLogic: UserLogic) {
|
||||
@GetMapping("logout")
|
||||
@PreAuthorize("isFullyAuthenticated()")
|
||||
fun logout(request: HttpServletRequest) =
|
||||
ok {
|
||||
userService.logout(request)
|
||||
userLogic.logout(request)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeViewCatalog
|
|||
import dev.fyloz.colorrecipesexplorer.model.Company
|
||||
import dev.fyloz.colorrecipesexplorer.model.CompanySaveDto
|
||||
import dev.fyloz.colorrecipesexplorer.model.CompanyUpdateDto
|
||||
import dev.fyloz.colorrecipesexplorer.service.CompanyService
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
|
@ -16,33 +15,33 @@ private const val COMPANY_CONTROLLER_PATH = "api/company"
|
|||
@RequestMapping(COMPANY_CONTROLLER_PATH)
|
||||
@Profile("!emergency")
|
||||
@PreAuthorizeViewCatalog
|
||||
class CompanyController(private val companyService: CompanyService) {
|
||||
class CompanyController(private val companyLogic: dev.fyloz.colorrecipesexplorer.logic.CompanyLogic) {
|
||||
@GetMapping
|
||||
fun getAll() =
|
||||
ok(companyService.getAllForOutput())
|
||||
ok(companyLogic.getAllForOutput())
|
||||
|
||||
@GetMapping("{id}")
|
||||
fun getById(@PathVariable id: Long) =
|
||||
ok(companyService.getByIdForOutput(id))
|
||||
ok(companyLogic.getByIdForOutput(id))
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAuthority('EDIT_COMPANIES')")
|
||||
fun save(@Valid @RequestBody company: CompanySaveDto) =
|
||||
created<Company>(COMPANY_CONTROLLER_PATH) {
|
||||
companyService.save(company)
|
||||
companyLogic.save(company)
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAuthority('EDIT_COMPANIES')")
|
||||
fun update(@Valid @RequestBody company: CompanyUpdateDto) =
|
||||
noContent {
|
||||
companyService.update(company)
|
||||
companyLogic.update(company)
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@PreAuthorize("hasAuthority('EDIT_COMPANIES')")
|
||||
fun deleteById(@PathVariable id: Long) =
|
||||
noContent {
|
||||
companyService.deleteById(id)
|
||||
companyLogic.deleteById(id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +1,35 @@
|
|||
package dev.fyloz.colorrecipesexplorer.rest
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.logic.config.ConfigurationLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.ConfigurationBase
|
||||
import dev.fyloz.colorrecipesexplorer.model.ConfigurationDto
|
||||
import dev.fyloz.colorrecipesexplorer.model.ConfigurationImageDto
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.Permission
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.toAuthority
|
||||
import dev.fyloz.colorrecipesexplorer.restartApplication
|
||||
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.security.core.Authentication
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
import javax.validation.constraints.NotBlank
|
||||
|
||||
@RestController
|
||||
@RequestMapping("api/config")
|
||||
class ConfigurationController(val configurationService: ConfigurationService) {
|
||||
class ConfigurationController(val configurationLogic: ConfigurationLogic) {
|
||||
@GetMapping
|
||||
fun getAll(@RequestParam(required = false) keys: String?, authentication: Authentication?) =
|
||||
ok(with(configurationService) {
|
||||
ok(with(configurationLogic) {
|
||||
if (keys != null) getAll(keys) else getAll()
|
||||
}.filter { authentication.hasAuthority(it) })
|
||||
|
||||
@GetMapping("{key}")
|
||||
fun get(@PathVariable key: String, authentication: Authentication?) = with(configurationService.get(key)) {
|
||||
fun get(@PathVariable key: String, authentication: Authentication?) = with(configurationLogic.get(key)) {
|
||||
if (authentication.hasAuthority(this)) ok(this) else forbidden()
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAuthority('ADMIN')")
|
||||
fun set(@RequestBody configurations: List<ConfigurationDto>) = noContent {
|
||||
configurationService.set(configurations)
|
||||
configurationLogic.set(configurations)
|
||||
}
|
||||
|
||||
@PostMapping("restart")
|
||||
|
@ -44,24 +42,24 @@ class ConfigurationController(val configurationService: ConfigurationService) {
|
|||
|
||||
@GetMapping("icon")
|
||||
fun getIcon() =
|
||||
okFile(configurationService.getConfiguredIcon(), MediaType.IMAGE_PNG_VALUE)
|
||||
okFile(configurationLogic.getConfiguredIcon(), MediaType.IMAGE_PNG_VALUE)
|
||||
|
||||
@PutMapping("icon")
|
||||
@PreAuthorize("hasAuthority('ADMIN')")
|
||||
fun setIcon(@RequestParam icon: MultipartFile) = noContent {
|
||||
configurationService.setConfiguredIcon(icon)
|
||||
configurationLogic.setConfiguredIcon(icon)
|
||||
}
|
||||
|
||||
// Logo
|
||||
|
||||
@GetMapping("logo")
|
||||
fun getLogo() =
|
||||
okFile(configurationService.getConfiguredLogo(), MediaType.IMAGE_PNG_VALUE)
|
||||
okFile(configurationLogic.getConfiguredLogo(), MediaType.IMAGE_PNG_VALUE)
|
||||
|
||||
@PutMapping("logo")
|
||||
@PreAuthorize("hasAuthority('ADMIN')")
|
||||
fun setLogo(@RequestParam logo: MultipartFile) = noContent {
|
||||
configurationService.setConfiguredLogo(logo)
|
||||
configurationLogic.setConfiguredLogo(logo)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package dev.fyloz.colorrecipesexplorer.rest
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.logic.config.ConfigurationLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.WriteableFileLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.ConfigurationType
|
||||
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.WriteableFileService
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
|
@ -15,14 +15,14 @@ const val FILE_CONTROLLER_PATH = "/api/file"
|
|||
@RestController
|
||||
@RequestMapping(FILE_CONTROLLER_PATH)
|
||||
class FileController(
|
||||
private val fileService: WriteableFileService,
|
||||
private val configService: ConfigurationService
|
||||
private val fileLogic: WriteableFileLogic,
|
||||
private val configurationLogic: ConfigurationLogic
|
||||
) {
|
||||
@GetMapping(produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE])
|
||||
fun upload(
|
||||
@RequestParam path: String,
|
||||
@RequestParam(required = false) mediaType: String?
|
||||
) = okFile(fileService.read(path), mediaType)
|
||||
) = okFile(fileLogic.read(path), mediaType)
|
||||
|
||||
@PutMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
|
||||
@PreAuthorize("hasAnyAuthority('WRITE_FILE')")
|
||||
|
@ -31,7 +31,7 @@ class FileController(
|
|||
@RequestParam path: String,
|
||||
@RequestParam(required = false) overwrite: Boolean = false
|
||||
): ResponseEntity<Void> {
|
||||
fileService.write(file, path, overwrite)
|
||||
fileLogic.write(file, path, overwrite)
|
||||
return created(path)
|
||||
}
|
||||
|
||||
|
@ -39,11 +39,11 @@ class FileController(
|
|||
@PreAuthorize("hasAnyAuthority('WRITE_FILE')")
|
||||
fun delete(@RequestParam path: String): ResponseEntity<Void> =
|
||||
noContent {
|
||||
fileService.delete(path)
|
||||
fileLogic.delete(path)
|
||||
}
|
||||
|
||||
private fun created(path: String): ResponseEntity<Void> =
|
||||
ResponseEntity
|
||||
.created(URI.create("${configService.get(ConfigurationType.INSTANCE_URL)}$FILE_CONTROLLER_PATH?path=$path"))
|
||||
.created(URI.create("${configurationLogic.get(ConfigurationType.INSTANCE_URL)}$FILE_CONTROLLER_PATH?path=$path"))
|
||||
.build()
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package dev.fyloz.colorrecipesexplorer.rest
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.logic.InventoryLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.MaterialQuantityDto
|
||||
import dev.fyloz.colorrecipesexplorer.model.MixDeductDto
|
||||
import dev.fyloz.colorrecipesexplorer.service.InventoryService
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.PutMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
|
@ -17,20 +16,20 @@ private const val INVENTORY_CONTROLLER_PATH = "api/inventory"
|
|||
@RequestMapping(INVENTORY_CONTROLLER_PATH)
|
||||
@Profile("!emergency")
|
||||
class InventoryController(
|
||||
private val inventoryService: InventoryService
|
||||
private val inventoryLogic: InventoryLogic
|
||||
) {
|
||||
@PutMapping("add")
|
||||
@PreAuthorize("hasAuthority('ADD_TO_INVENTORY')")
|
||||
fun add(@RequestBody quantities: Collection<MaterialQuantityDto>) =
|
||||
ok(inventoryService.add(quantities))
|
||||
ok(inventoryLogic.add(quantities))
|
||||
|
||||
@PutMapping("deduct")
|
||||
@PreAuthorize("hasAuthority('DEDUCT_FROM_INVENTORY')")
|
||||
fun deduct(@RequestBody quantities: Collection<MaterialQuantityDto>) =
|
||||
ok(inventoryService.deduct(quantities))
|
||||
ok(inventoryLogic.deduct(quantities))
|
||||
|
||||
@PutMapping("deduct/mix")
|
||||
@PreAuthorize("hasAuthority('DEDUCT_FROM_INVENTORY')")
|
||||
fun deduct(@RequestBody mixRatio: MixDeductDto) =
|
||||
ok(inventoryService.deductMix(mixRatio))
|
||||
ok(inventoryLogic.deductMix(mixRatio))
|
||||
}
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
package dev.fyloz.colorrecipesexplorer.rest
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeViewCatalog
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties
|
||||
import dev.fyloz.colorrecipesexplorer.logic.MaterialLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.service.MaterialService
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
import java.net.URI
|
||||
import javax.validation.Valid
|
||||
|
||||
private const val MATERIAL_CONTROLLER_PATH = "api/material"
|
||||
|
@ -20,25 +17,25 @@ private const val MATERIAL_CONTROLLER_PATH = "api/material"
|
|||
@Profile("!emergency")
|
||||
@PreAuthorizeViewCatalog
|
||||
class MaterialController(
|
||||
private val materialService: MaterialService
|
||||
private val materialLogic: MaterialLogic
|
||||
) {
|
||||
@GetMapping
|
||||
fun getAll() =
|
||||
ok(materialService.getAllForOutput())
|
||||
ok(materialLogic.getAllForOutput())
|
||||
|
||||
@GetMapping("notmixtype")
|
||||
fun getAllNotMixType() =
|
||||
ok(materialService.getAllNotMixType())
|
||||
ok(materialLogic.getAllNotMixType())
|
||||
|
||||
@GetMapping("{id}")
|
||||
fun getById(@PathVariable id: Long) =
|
||||
ok(materialService.getByIdForOutput(id))
|
||||
ok(materialLogic.getByIdForOutput(id))
|
||||
|
||||
@PostMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
|
||||
@PreAuthorize("hasAuthority('EDIT_MATERIALS')")
|
||||
fun save(@Valid material: MaterialSaveDto, simdutFile: MultipartFile?) =
|
||||
created<MaterialOutputDto>(MATERIAL_CONTROLLER_PATH) {
|
||||
with(materialService) {
|
||||
with(materialLogic) {
|
||||
save(
|
||||
materialSaveDto(
|
||||
name = material.name,
|
||||
|
@ -54,7 +51,7 @@ class MaterialController(
|
|||
@PreAuthorize("hasAuthority('EDIT_MATERIALS')")
|
||||
fun update(@Valid material: MaterialUpdateDto, simdutFile: MultipartFile?) =
|
||||
noContent {
|
||||
materialService.update(
|
||||
materialLogic.update(
|
||||
materialUpdateDto(
|
||||
id = material.id,
|
||||
name = material.name,
|
||||
|
@ -69,15 +66,15 @@ class MaterialController(
|
|||
@PreAuthorize("hasAuthority('EDIT_MATERIALS')")
|
||||
fun deleteById(@PathVariable id: Long) =
|
||||
noContent {
|
||||
materialService.deleteById(id)
|
||||
materialLogic.deleteById(id)
|
||||
}
|
||||
|
||||
@GetMapping("mix/create/{recipeId}")
|
||||
fun getAllForMixCreation(@PathVariable recipeId: Long) =
|
||||
ok(materialService.getAllForMixCreation(recipeId))
|
||||
ok(materialLogic.getAllForMixCreation(recipeId))
|
||||
|
||||
@GetMapping("mix/update/{mixId}")
|
||||
fun getAllForMixUpdate(@PathVariable mixId: Long) =
|
||||
ok(materialService.getAllForMixUpdate(mixId))
|
||||
ok(materialLogic.getAllForMixUpdate(mixId))
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package dev.fyloz.colorrecipesexplorer.rest
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeViewCatalog
|
||||
import dev.fyloz.colorrecipesexplorer.logic.MaterialTypeLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.MaterialType
|
||||
import dev.fyloz.colorrecipesexplorer.model.MaterialTypeSaveDto
|
||||
import dev.fyloz.colorrecipesexplorer.model.MaterialTypeUpdateDto
|
||||
import dev.fyloz.colorrecipesexplorer.service.MaterialTypeService
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
|
@ -16,34 +16,34 @@ private const val MATERIAL_TYPE_CONTROLLER_PATH = "api/materialtype"
|
|||
@RequestMapping(MATERIAL_TYPE_CONTROLLER_PATH)
|
||||
@Profile("!emergency")
|
||||
@PreAuthorizeViewCatalog
|
||||
class MaterialTypeController(private val materialTypeService: MaterialTypeService) {
|
||||
class MaterialTypeController(private val materialTypeLogic: MaterialTypeLogic) {
|
||||
@GetMapping
|
||||
fun getAll() =
|
||||
ok(materialTypeService.getAllForOutput())
|
||||
ok(materialTypeLogic.getAllForOutput())
|
||||
|
||||
@GetMapping("{id}")
|
||||
fun getById(@PathVariable id: Long) =
|
||||
ok(materialTypeService.getByIdForOutput(id))
|
||||
ok(materialTypeLogic.getByIdForOutput(id))
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')")
|
||||
fun save(@Valid @RequestBody materialType: MaterialTypeSaveDto) =
|
||||
created<MaterialType>(MATERIAL_TYPE_CONTROLLER_PATH) {
|
||||
materialTypeService.save(materialType)
|
||||
materialTypeLogic.save(materialType)
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')")
|
||||
fun update(@Valid @RequestBody materialType: MaterialTypeUpdateDto) =
|
||||
noContent {
|
||||
materialTypeService.update(materialType)
|
||||
materialTypeLogic.update(materialType)
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')")
|
||||
fun deleteById(@PathVariable id: Long) =
|
||||
noContent {
|
||||
materialTypeService.deleteById(id)
|
||||
materialTypeLogic.deleteById(id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@ package dev.fyloz.colorrecipesexplorer.rest
|
|||
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeEditRecipes
|
||||
import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeViewRecipes
|
||||
import dev.fyloz.colorrecipesexplorer.logic.MixLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.RecipeImageLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.RecipeLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.service.MixService
|
||||
import dev.fyloz.colorrecipesexplorer.service.RecipeImageService
|
||||
import dev.fyloz.colorrecipesexplorer.service.RecipeService
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.ResponseEntity
|
||||
|
@ -23,27 +23,27 @@ private const val MIX_CONTROLLER_PATH = "api/recipe/mix"
|
|||
@Profile("!emergency")
|
||||
@PreAuthorizeViewRecipes
|
||||
class RecipeController(
|
||||
private val recipeService: RecipeService,
|
||||
private val recipeImageService: RecipeImageService
|
||||
private val recipeLogic: RecipeLogic,
|
||||
private val recipeImageLogic: RecipeImageLogic
|
||||
) {
|
||||
@GetMapping
|
||||
fun getAll(@RequestParam(required = false) name: String?) =
|
||||
if (name == null)
|
||||
ok(recipeService.getAllForOutput())
|
||||
ok(recipeLogic.getAllForOutput())
|
||||
else
|
||||
ok(with(recipeService) {
|
||||
ok(with(recipeLogic) {
|
||||
getAllByName(name).map { it.toOutput() }
|
||||
})
|
||||
|
||||
@GetMapping("{id}")
|
||||
fun getById(@PathVariable id: Long) =
|
||||
ok(recipeService.getByIdForOutput(id))
|
||||
ok(recipeLogic.getByIdForOutput(id))
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorizeEditRecipes
|
||||
fun save(@Valid @RequestBody recipe: RecipeSaveDto) =
|
||||
created<RecipeOutputDto>(RECIPE_CONTROLLER_PATH) {
|
||||
with(recipeService) {
|
||||
with(recipeLogic) {
|
||||
save(recipe).toOutput()
|
||||
}
|
||||
}
|
||||
|
@ -52,27 +52,27 @@ class RecipeController(
|
|||
@PreAuthorizeEditRecipes
|
||||
fun update(@Valid @RequestBody recipe: RecipeUpdateDto) =
|
||||
noContent {
|
||||
recipeService.update(recipe)
|
||||
recipeLogic.update(recipe)
|
||||
}
|
||||
|
||||
@PutMapping("public")
|
||||
@PreAuthorize("hasAuthority('EDIT_RECIPES_PUBLIC_DATA')")
|
||||
fun updatePublicData(@Valid @RequestBody publicDataDto: RecipePublicDataDto) =
|
||||
noContent {
|
||||
recipeService.updatePublicData(publicDataDto)
|
||||
recipeLogic.updatePublicData(publicDataDto)
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@PreAuthorizeEditRecipes
|
||||
fun deleteById(@PathVariable id: Long) =
|
||||
noContent {
|
||||
recipeService.deleteById(id)
|
||||
recipeLogic.deleteById(id)
|
||||
}
|
||||
|
||||
@PutMapping("{recipeId}/image", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
|
||||
@PreAuthorizeEditRecipes
|
||||
fun downloadImage(@PathVariable recipeId: Long, image: MultipartFile): ResponseEntity<RecipeOutputDto> {
|
||||
recipeImageService.download(image, recipeService.getById(recipeId))
|
||||
recipeImageLogic.download(image, recipeLogic.getById(recipeId))
|
||||
return getById(recipeId)
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ class RecipeController(
|
|||
@PreAuthorizeEditRecipes
|
||||
fun deleteImage(@PathVariable recipeId: Long, @PathVariable name: String) =
|
||||
noContent {
|
||||
recipeImageService.delete(recipeService.getById(recipeId), name)
|
||||
recipeImageLogic.delete(recipeLogic.getById(recipeId), name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,29 +88,29 @@ class RecipeController(
|
|||
@RequestMapping(MIX_CONTROLLER_PATH)
|
||||
@Profile("!emergency")
|
||||
@PreAuthorizeViewRecipes
|
||||
class MixController(private val mixService: MixService) {
|
||||
class MixController(private val mixLogic: MixLogic) {
|
||||
@GetMapping("{id}")
|
||||
fun getById(@PathVariable id: Long) =
|
||||
ok(mixService.getByIdForOutput(id))
|
||||
ok(mixLogic.getByIdForOutput(id))
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorizeEditRecipes
|
||||
fun save(@Valid @RequestBody mix: MixSaveDto) =
|
||||
created<Mix>(MIX_CONTROLLER_PATH) {
|
||||
mixService.save(mix)
|
||||
mixLogic.save(mix)
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@PreAuthorizeEditRecipes
|
||||
fun update(@Valid @RequestBody mix: MixUpdateDto) =
|
||||
noContent {
|
||||
mixService.update(mix)
|
||||
mixLogic.update(mix)
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@PreAuthorizeEditRecipes
|
||||
fun deleteById(@PathVariable id: Long) =
|
||||
noContent {
|
||||
mixService.deleteById(id)
|
||||
mixLogic.deleteById(id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package dev.fyloz.colorrecipesexplorer.rest
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.logic.TouchUpKitLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.touchupkit.TouchUpKitOutputDto
|
||||
import dev.fyloz.colorrecipesexplorer.model.touchupkit.TouchUpKitSaveDto
|
||||
import dev.fyloz.colorrecipesexplorer.model.touchupkit.TouchUpKitUpdateDto
|
||||
import dev.fyloz.colorrecipesexplorer.service.TouchUpKitService
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.core.io.Resource
|
||||
import org.springframework.http.MediaType
|
||||
|
@ -19,21 +19,21 @@ const val TOUCH_UP_KIT_CONTROLLER_PATH = "/api/touchupkit"
|
|||
@Profile("!emergency")
|
||||
@PreAuthorize("hasAuthority('VIEW_TOUCH_UP_KITS')")
|
||||
class TouchUpKitController(
|
||||
private val touchUpKitService: TouchUpKitService
|
||||
private val touchUpKitLogic: TouchUpKitLogic
|
||||
) {
|
||||
@GetMapping
|
||||
fun getAll() =
|
||||
ok(touchUpKitService.getAllForOutput())
|
||||
ok(touchUpKitLogic.getAllForOutput())
|
||||
|
||||
@GetMapping("{id}")
|
||||
fun getById(@PathVariable id: Long) =
|
||||
ok(touchUpKitService.getByIdForOutput(id))
|
||||
ok(touchUpKitLogic.getByIdForOutput(id))
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')")
|
||||
fun save(@Valid @RequestBody touchUpKit: TouchUpKitSaveDto) =
|
||||
created<TouchUpKitOutputDto>(TOUCH_UP_KIT_CONTROLLER_PATH) {
|
||||
with(touchUpKitService) {
|
||||
with(touchUpKitLogic) {
|
||||
save(touchUpKit).toOutput()
|
||||
}
|
||||
}
|
||||
|
@ -41,24 +41,24 @@ class TouchUpKitController(
|
|||
@PutMapping
|
||||
@PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')")
|
||||
fun update(@Valid @RequestBody touchUpKit: TouchUpKitUpdateDto) = noContent {
|
||||
touchUpKitService.update(touchUpKit)
|
||||
touchUpKitLogic.update(touchUpKit)
|
||||
}
|
||||
|
||||
@PutMapping("{id}/complete")
|
||||
@PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')")
|
||||
fun complete(@PathVariable id: Long) = noContent {
|
||||
touchUpKitService.complete(id)
|
||||
touchUpKitLogic.complete(id)
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')")
|
||||
fun deleteById(@PathVariable id: Long) = noContent {
|
||||
touchUpKitService.deleteById(id)
|
||||
touchUpKitLogic.deleteById(id)
|
||||
}
|
||||
|
||||
@GetMapping("pdf")
|
||||
fun getJobPdf(@RequestParam project: String): ResponseEntity<Resource> {
|
||||
with(touchUpKitService.generateJobPdfResource(project)) {
|
||||
with(touchUpKitLogic.generateJobPdfResource(project)) {
|
||||
return ResponseEntity.ok()
|
||||
.header("Content-Disposition", "filename=TouchUpKit_$project.pdf")
|
||||
.contentLength(this.contentLength())
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
||||
|
@ -16,11 +16,11 @@ import java.util.*
|
|||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
import dev.fyloz.colorrecipesexplorer.service.AbstractServiceTest as AbstractServiceTest1
|
||||
import dev.fyloz.colorrecipesexplorer.logic.AbstractServiceTest as AbstractServiceTest1
|
||||
|
||||
abstract class AbstractServiceTest<E, S : Service<E, *>, R : JpaRepository<E, *>> {
|
||||
protected abstract val repository: R
|
||||
protected abstract val service: S
|
||||
protected abstract val logic: S
|
||||
|
||||
protected abstract val entity: E
|
||||
protected abstract val anotherEntity: E
|
||||
|
@ -33,7 +33,7 @@ abstract class AbstractServiceTest<E, S : Service<E, *>, R : JpaRepository<E, *>
|
|||
|
||||
@AfterEach
|
||||
open fun afterEach() {
|
||||
reset(repository, service)
|
||||
reset(repository, logic)
|
||||
}
|
||||
|
||||
// getAll()
|
||||
|
@ -42,7 +42,7 @@ abstract class AbstractServiceTest<E, S : Service<E, *>, R : JpaRepository<E, *>
|
|||
open fun `getAll() returns all available entities`() {
|
||||
whenever(repository.findAll()).doReturn(entityList)
|
||||
|
||||
val found = service.getAll()
|
||||
val found = logic.getAll()
|
||||
|
||||
assertEquals(entityList, found)
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ abstract class AbstractServiceTest<E, S : Service<E, *>, R : JpaRepository<E, *>
|
|||
open fun `getAll() returns empty list when there is no entities`() {
|
||||
whenever(repository.findAll()).doReturn(listOf())
|
||||
|
||||
val found = service.getAll()
|
||||
val found = logic.getAll()
|
||||
|
||||
assertTrue { found.isEmpty() }
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ abstract class AbstractServiceTest<E, S : Service<E, *>, R : JpaRepository<E, *>
|
|||
open fun `save() saves in the repository and returns the saved value`() {
|
||||
whenever(repository.save(entity)).doReturn(entity)
|
||||
|
||||
val found = service.save(entity)
|
||||
val found = logic.save(entity)
|
||||
|
||||
verify(repository).save(entity)
|
||||
assertEquals(entity, found)
|
||||
|
@ -74,7 +74,7 @@ abstract class AbstractServiceTest<E, S : Service<E, *>, R : JpaRepository<E, *>
|
|||
open fun `update() saves in the repository and returns the updated value`() {
|
||||
whenever(repository.save(entity)).doReturn(entity)
|
||||
|
||||
val found = service.update(entity)
|
||||
val found = logic.update(entity)
|
||||
|
||||
verify(repository).save(entity)
|
||||
assertEquals(entity, found)
|
||||
|
@ -84,7 +84,7 @@ abstract class AbstractServiceTest<E, S : Service<E, *>, R : JpaRepository<E, *>
|
|||
|
||||
@Test
|
||||
open fun `delete() deletes in the repository`() {
|
||||
service.delete(entity)
|
||||
logic.delete(entity)
|
||||
|
||||
verify(repository).delete(entity)
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ abstract class AbstractModelServiceTest<E : Model, S : ModelService<E, *>, R : J
|
|||
open fun `existsById() returns true when an entity with the given id exists in the repository`() {
|
||||
whenever(repository.existsById(entity.id!!)).doReturn(true)
|
||||
|
||||
val found = service.existsById(entity.id!!)
|
||||
val found = logic.existsById(entity.id!!)
|
||||
|
||||
assertTrue(found)
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ abstract class AbstractModelServiceTest<E : Model, S : ModelService<E, *>, R : J
|
|||
open fun `existsById() returns false when no entity with the given id exists in the repository`() {
|
||||
whenever(repository.existsById(entity.id!!)).doReturn(false)
|
||||
|
||||
val found = service.existsById(entity.id!!)
|
||||
val found = logic.existsById(entity.id!!)
|
||||
|
||||
assertFalse(found)
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ abstract class AbstractModelServiceTest<E : Model, S : ModelService<E, *>, R : J
|
|||
open fun `getById() returns the entity with the given id from the repository`() {
|
||||
whenever(repository.findById(entity.id!!)).doReturn(Optional.of(entity))
|
||||
|
||||
val found = service.getById(entity.id!!)
|
||||
val found = logic.getById(entity.id!!)
|
||||
|
||||
assertEquals(entity, found)
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ abstract class AbstractModelServiceTest<E : Model, S : ModelService<E, *>, R : J
|
|||
open fun `getById() throws NotFoundException when no entity with the given id exists in the repository`() {
|
||||
whenever(repository.findById(entity.id!!)).doReturn(Optional.empty())
|
||||
|
||||
assertThrows<NotFoundException> { service.getById(entity.id!!) }
|
||||
assertThrows<NotFoundException> { logic.getById(entity.id!!) }
|
||||
.assertErrorCode()
|
||||
}
|
||||
|
||||
|
@ -136,9 +136,9 @@ abstract class AbstractModelServiceTest<E : Model, S : ModelService<E, *>, R : J
|
|||
|
||||
@Test
|
||||
open fun `save() throws AlreadyExistsException when an entity with the given id exists in the repository`() {
|
||||
doReturn(true).whenever(service).existsById(entity.id!!)
|
||||
doReturn(true).whenever(logic).existsById(entity.id!!)
|
||||
|
||||
assertThrows<AlreadyExistsException> { service.save(entity) }
|
||||
assertThrows<AlreadyExistsException> { logic.save(entity) }
|
||||
.assertErrorCode()
|
||||
}
|
||||
|
||||
|
@ -147,10 +147,10 @@ abstract class AbstractModelServiceTest<E : Model, S : ModelService<E, *>, R : J
|
|||
@Test
|
||||
override fun `update() saves in the repository and returns the updated value`() {
|
||||
whenever(repository.save(entity)).doReturn(entity)
|
||||
doReturn(true).whenever(service).existsById(entity.id!!)
|
||||
doReturn(entity).whenever(service).getById(entity.id!!)
|
||||
doReturn(true).whenever(logic).existsById(entity.id!!)
|
||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||
|
||||
val found = service.update(entity)
|
||||
val found = logic.update(entity)
|
||||
|
||||
verify(repository).save(entity)
|
||||
assertEquals(entity, found)
|
||||
|
@ -158,9 +158,9 @@ abstract class AbstractModelServiceTest<E : Model, S : ModelService<E, *>, R : J
|
|||
|
||||
@Test
|
||||
open fun `update() throws NotFoundException when no entity with the given id exists in the repository`() {
|
||||
doReturn(false).whenever(service).existsById(entity.id!!)
|
||||
doReturn(false).whenever(logic).existsById(entity.id!!)
|
||||
|
||||
assertThrows<NotFoundException> { service.update(entity) }
|
||||
assertThrows<NotFoundException> { logic.update(entity) }
|
||||
.assertErrorCode()
|
||||
}
|
||||
|
||||
|
@ -168,9 +168,9 @@ abstract class AbstractModelServiceTest<E : Model, S : ModelService<E, *>, R : J
|
|||
|
||||
@Test
|
||||
open fun `deleteById() deletes the entity with the given id in the repository`() {
|
||||
doReturn(entity).whenever(service).getById(entity.id!!)
|
||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||
|
||||
service.deleteById(entity.id!!)
|
||||
logic.deleteById(entity.id!!)
|
||||
|
||||
verify(repository).delete(entity)
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ abstract class AbstractNamedModelServiceTest<E : NamedModel, S : NamedModelServi
|
|||
open fun `existsByName() returns true when an entity with the given name exists`() {
|
||||
whenever(repository.existsByName(entity.name)).doReturn(true)
|
||||
|
||||
val found = service.existsByName(entity.name)
|
||||
val found = logic.existsByName(entity.name)
|
||||
|
||||
assertTrue(found)
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ abstract class AbstractNamedModelServiceTest<E : NamedModel, S : NamedModelServi
|
|||
open fun `existsByName() returns false when no entity with the given name exists`() {
|
||||
whenever(repository.existsByName(entity.name)).doReturn(false)
|
||||
|
||||
val found = service.existsByName(entity.name)
|
||||
val found = logic.existsByName(entity.name)
|
||||
|
||||
assertFalse(found)
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ abstract class AbstractNamedModelServiceTest<E : NamedModel, S : NamedModelServi
|
|||
open fun `getByName() returns the entity with the given name`() {
|
||||
whenever(repository.findByName(entity.name)).doReturn(entity)
|
||||
|
||||
val found = service.getByName(entity.name)
|
||||
val found = logic.getByName(entity.name)
|
||||
|
||||
assertEquals(entity, found)
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ abstract class AbstractNamedModelServiceTest<E : NamedModel, S : NamedModelServi
|
|||
open fun `getByName() throws NotFoundException when no entity with the given name exists`() {
|
||||
whenever(repository.findByName(entity.name)).doReturn(null)
|
||||
|
||||
assertThrows<NotFoundException> { service.getByName(entity.name) }
|
||||
assertThrows<NotFoundException> { logic.getByName(entity.name) }
|
||||
.assertErrorCode("name")
|
||||
}
|
||||
|
||||
|
@ -223,9 +223,9 @@ abstract class AbstractNamedModelServiceTest<E : NamedModel, S : NamedModelServi
|
|||
|
||||
@Test
|
||||
open fun `save() throws AlreadyExistsException when an entity with the given name exists`() {
|
||||
doReturn(true).whenever(service).existsByName(entity.name)
|
||||
doReturn(true).whenever(logic).existsByName(entity.name)
|
||||
|
||||
assertThrows<AlreadyExistsException> { service.save(entity) }
|
||||
assertThrows<AlreadyExistsException> { logic.save(entity) }
|
||||
.assertErrorCode("name")
|
||||
}
|
||||
|
||||
|
@ -235,10 +235,10 @@ abstract class AbstractNamedModelServiceTest<E : NamedModel, S : NamedModelServi
|
|||
override fun `update() saves in the repository and returns the updated value`() {
|
||||
whenever(repository.save(entity)).doReturn(entity)
|
||||
whenever(repository.findByName(entity.name)).doReturn(null)
|
||||
doReturn(true).whenever(service).existsById(entity.id!!)
|
||||
doReturn(entity).whenever(service).getById(entity.id!!)
|
||||
doReturn(true).whenever(logic).existsById(entity.id!!)
|
||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||
|
||||
val found = service.update(entity)
|
||||
val found = logic.update(entity)
|
||||
|
||||
verify(repository).save(entity)
|
||||
assertEquals(entity, found)
|
||||
|
@ -247,17 +247,17 @@ abstract class AbstractNamedModelServiceTest<E : NamedModel, S : NamedModelServi
|
|||
@Test
|
||||
override fun `update() throws NotFoundException when no entity with the given id exists in the repository`() {
|
||||
whenever(repository.findByName(entity.name)).doReturn(null)
|
||||
doReturn(false).whenever(service).existsById(entity.id!!)
|
||||
doReturn(false).whenever(logic).existsById(entity.id!!)
|
||||
|
||||
assertThrows<NotFoundException> { service.update(entity) }
|
||||
assertThrows<NotFoundException> { logic.update(entity) }
|
||||
}
|
||||
|
||||
@Test
|
||||
open fun `update() throws AlreadyExistsException when an entity with the updated name exists`() {
|
||||
whenever(repository.findByName(entity.name)).doReturn(entityWithEntityName)
|
||||
doReturn(entity).whenever(service).getById(entity.id!!)
|
||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||
|
||||
assertThrows<AlreadyExistsException> { service.update(entity) }
|
||||
assertThrows<AlreadyExistsException> { logic.update(entity) }
|
||||
.assertErrorCode("name")
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import dev.fyloz.colorrecipesexplorer.config.security.defaultGroupCookieName
|
||||
|
@ -7,7 +7,7 @@ import dev.fyloz.colorrecipesexplorer.exception.NotFoundException
|
|||
import dev.fyloz.colorrecipesexplorer.model.account.*
|
||||
import dev.fyloz.colorrecipesexplorer.repository.GroupRepository
|
||||
import dev.fyloz.colorrecipesexplorer.repository.UserRepository
|
||||
import dev.fyloz.colorrecipesexplorer.service.users.*
|
||||
import dev.fyloz.colorrecipesexplorer.logic.users.*
|
||||
import org.junit.jupiter.api.*
|
||||
import org.springframework.mock.web.MockHttpServletResponse
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException
|
||||
|
@ -21,8 +21,8 @@ import kotlin.test.assertNotNull
|
|||
import kotlin.test.assertTrue
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class UserServiceTest :
|
||||
AbstractExternalModelServiceTest<User, UserSaveDto, UserUpdateDto, UserService, UserRepository>() {
|
||||
class UserLogicTest :
|
||||
AbstractExternalModelServiceTest<User, UserSaveDto, UserUpdateDto, UserLogic, UserRepository>() {
|
||||
private val passwordEncoder = BCryptPasswordEncoder()
|
||||
|
||||
override val entity: User = user(id = 0L, passwordEncoder = passwordEncoder)
|
||||
|
@ -34,8 +34,8 @@ class UserServiceTest :
|
|||
override val entityUpdateDto: UserUpdateDto = spy(userUpdateDto(id = 0L))
|
||||
|
||||
override val repository: UserRepository = mock()
|
||||
private val groupService: GroupService = mock()
|
||||
override val service: UserService = spy(UserServiceImpl(repository, groupService))
|
||||
private val groupService: GroupLogic = mock()
|
||||
override val logic: UserLogic = spy(DefaultUserLogic(repository, groupService))
|
||||
|
||||
private val entitySaveDtoUser = User(
|
||||
entitySaveDto.id,
|
||||
|
@ -60,7 +60,7 @@ class UserServiceTest :
|
|||
fun `existsByFirstNameAndLastName() returns true when an user with the given first name and last name exists`() {
|
||||
whenever(repository.existsByFirstNameAndLastName(entity.firstName, entity.lastName)).doReturn(true)
|
||||
|
||||
val found = service.existsByFirstNameAndLastName(entity.firstName, entity.lastName)
|
||||
val found = logic.existsByFirstNameAndLastName(entity.firstName, entity.lastName)
|
||||
|
||||
assertTrue(found)
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ class UserServiceTest :
|
|||
fun `existsByFirstNameAndLastName() returns false when no user with the given first name and last name exists`() {
|
||||
whenever(repository.existsByFirstNameAndLastName(entity.firstName, entity.lastName)).doReturn(false)
|
||||
|
||||
val found = service.existsByFirstNameAndLastName(entity.firstName, entity.lastName)
|
||||
val found = logic.existsByFirstNameAndLastName(entity.firstName, entity.lastName)
|
||||
|
||||
assertFalse(found)
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ class UserServiceTest :
|
|||
whenever(repository.findById(entityDefaultGroupUser.id)).doReturn(Optional.of(entityDefaultGroupUser))
|
||||
|
||||
assertThrows<NotFoundException> {
|
||||
service.getById(
|
||||
logic.getById(
|
||||
entityDefaultGroupUser.id,
|
||||
ignoreDefaultGroupUsers = true,
|
||||
ignoreSystemUsers = false
|
||||
|
@ -94,7 +94,7 @@ class UserServiceTest :
|
|||
whenever(repository.findById(entitySystemUser.id)).doReturn(Optional.of(entitySystemUser))
|
||||
|
||||
assertThrows<NotFoundException> {
|
||||
service.getById(
|
||||
logic.getById(
|
||||
entitySystemUser.id,
|
||||
ignoreDefaultGroupUsers = false,
|
||||
ignoreSystemUsers = true
|
||||
|
@ -108,7 +108,7 @@ class UserServiceTest :
|
|||
fun `getByGroup() returns all the users with the given group from the repository`() {
|
||||
whenever(repository.findAllByGroup(group)).doReturn(entityList)
|
||||
|
||||
val found = service.getByGroup(group)
|
||||
val found = logic.getByGroup(group)
|
||||
|
||||
assertTrue(found.containsAll(entityList))
|
||||
assertTrue(entityList.containsAll(found))
|
||||
|
@ -118,7 +118,7 @@ class UserServiceTest :
|
|||
fun `getByGroup() returns an empty list when there is no user with the given group in the repository`() {
|
||||
whenever(repository.findAllByGroup(group)).doReturn(listOf())
|
||||
|
||||
val found = service.getByGroup(group)
|
||||
val found = logic.getByGroup(group)
|
||||
|
||||
assertTrue(found.isEmpty())
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ class UserServiceTest :
|
|||
fun `getDefaultGroupUser() returns the default user of the given group from the repository`() {
|
||||
whenever(repository.findByIsDefaultGroupUserIsTrueAndGroupIs(group)).doReturn(entityDefaultGroupUser)
|
||||
|
||||
val found = service.getDefaultGroupUser(group)
|
||||
val found = logic.getDefaultGroupUser(group)
|
||||
|
||||
assertEquals(entityDefaultGroupUser, found)
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ class UserServiceTest :
|
|||
whenever(repository.save(entity)).doReturn(entity)
|
||||
doReturn(false).whenever(repository).existsByFirstNameAndLastName(entity.firstName, entity.lastName)
|
||||
|
||||
val found = service.save(entity)
|
||||
val found = logic.save(entity)
|
||||
|
||||
verify(repository).save(entity)
|
||||
assertEquals(entity, found)
|
||||
|
@ -150,13 +150,13 @@ class UserServiceTest :
|
|||
fun `save() throws AlreadyExistsException when firstName and lastName exists`() {
|
||||
doReturn(true).whenever(repository).existsByFirstNameAndLastName(entity.firstName, entity.lastName)
|
||||
|
||||
assertThrows<AlreadyExistsException> { service.save(entity) }
|
||||
assertThrows<AlreadyExistsException> { logic.save(entity) }
|
||||
.assertErrorCode("fullName")
|
||||
}
|
||||
|
||||
@Test
|
||||
override fun `save(dto) calls and returns save() with the created entity`() {
|
||||
withBaseSaveDtoTest(entity, entitySaveDto, service, {
|
||||
withBaseSaveDtoTest(entity, entitySaveDto, logic, {
|
||||
argThat {
|
||||
this.id == entity.id && this.firstName == entity.firstName && this.lastName == entity.lastName
|
||||
}
|
||||
|
@ -165,11 +165,11 @@ class UserServiceTest :
|
|||
|
||||
@Test
|
||||
fun `save(dto) calls and returns save() with the created user`() {
|
||||
doReturn(entitySaveDtoUser).whenever(service).save(any<User>())
|
||||
doReturn(entitySaveDtoUser).whenever(logic).save(any<User>())
|
||||
|
||||
val found = service.save(entitySaveDto)
|
||||
val found = logic.save(entitySaveDto)
|
||||
|
||||
verify(service).save(argThat<User> { this.id == entity.id && this.firstName == entity.firstName && this.lastName == entity.lastName })
|
||||
verify(logic).save(argThat<User> { this.id == entity.id && this.firstName == entity.firstName && this.lastName == entity.lastName })
|
||||
assertEquals(entitySaveDtoUser, found)
|
||||
}
|
||||
|
||||
|
@ -177,17 +177,17 @@ class UserServiceTest :
|
|||
|
||||
@Test
|
||||
override fun `update(dto) calls and returns update() with the created entity`() =
|
||||
withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() })
|
||||
withBaseUpdateDtoTest(entity, entityUpdateDto, logic, { any() })
|
||||
|
||||
@Test
|
||||
fun `update() throws AlreadyExistsException when a different user with the given first name and last name exists`() {
|
||||
whenever(repository.findByFirstNameAndLastName(entity.firstName, entity.lastName)).doReturn(
|
||||
entityDefaultGroupUser
|
||||
)
|
||||
doReturn(entity).whenever(service).getById(eq(entity.id), any(), any())
|
||||
doReturn(entity).whenever(logic).getById(eq(entity.id), any(), any())
|
||||
|
||||
assertThrows<AlreadyExistsException> {
|
||||
service.update(
|
||||
logic.update(
|
||||
entity,
|
||||
true,
|
||||
ignoreSystemUsers = true
|
||||
|
@ -197,11 +197,11 @@ class UserServiceTest :
|
|||
}
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class GroupServiceTest :
|
||||
AbstractExternalNamedModelServiceTest<Group, GroupSaveDto, GroupUpdateDto, GroupService, GroupRepository>() {
|
||||
private val userService: UserService = mock()
|
||||
class GroupLogicTest :
|
||||
AbstractExternalNamedModelServiceTest<Group, GroupSaveDto, GroupUpdateDto, GroupLogic, GroupRepository>() {
|
||||
private val userService: UserLogic = mock()
|
||||
override val repository: GroupRepository = mock()
|
||||
override val service: GroupServiceImpl = spy(GroupServiceImpl(userService, repository))
|
||||
override val logic: DefaultGroupLogic = spy(DefaultGroupLogic(userService, repository))
|
||||
|
||||
override val entity: Group = group(id = 0L, name = "group")
|
||||
override val anotherEntity: Group = group(id = 1L, name = "another group")
|
||||
|
@ -224,10 +224,10 @@ class GroupServiceTest :
|
|||
fun `getUsersForGroup() returns all users in the given group`() {
|
||||
val group = group(id = 1L)
|
||||
|
||||
doReturn(group).whenever(service).getById(group.id!!)
|
||||
doReturn(group).whenever(logic).getById(group.id!!)
|
||||
whenever(userService.getByGroup(group)).doReturn(listOf(groupUser))
|
||||
|
||||
val found = service.getUsersForGroup(group.id!!)
|
||||
val found = logic.getUsersForGroup(group.id!!)
|
||||
|
||||
assertTrue(found.contains(groupUser))
|
||||
assertTrue(found.size == 1)
|
||||
|
@ -235,9 +235,9 @@ class GroupServiceTest :
|
|||
|
||||
@Test
|
||||
fun `getUsersForGroup() returns empty collection when the given group contains any user`() {
|
||||
doReturn(entity).whenever(service).getById(entity.id!!)
|
||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||
|
||||
val found = service.getUsersForGroup(entity.id!!)
|
||||
val found = logic.getUsersForGroup(entity.id!!)
|
||||
|
||||
assertTrue(found.isEmpty())
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ class GroupServiceTest :
|
|||
whenever(request.cookies).doReturn(cookies)
|
||||
whenever(userService.getById(eq(groupUserId), any(), any())).doReturn(groupUser)
|
||||
|
||||
val found = service.getRequestDefaultGroup(request)
|
||||
val found = logic.getRequestDefaultGroup(request)
|
||||
|
||||
assertEquals(entity, found)
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ class GroupServiceTest :
|
|||
|
||||
whenever(request.cookies).doReturn(arrayOf())
|
||||
|
||||
assertThrows<NoDefaultGroupException> { service.getRequestDefaultGroup(request) }
|
||||
assertThrows<NoDefaultGroupException> { logic.getRequestDefaultGroup(request) }
|
||||
}
|
||||
|
||||
// setResponseDefaultGroup()
|
||||
|
@ -273,9 +273,9 @@ class GroupServiceTest :
|
|||
val response = MockHttpServletResponse()
|
||||
|
||||
whenever(userService.getDefaultGroupUser(entity)).doReturn(groupUser)
|
||||
doReturn(entity).whenever(service).getById(entity.id!!)
|
||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||
|
||||
service.setResponseDefaultGroup(entity.id!!, response)
|
||||
logic.setResponseDefaultGroup(entity.id!!, response)
|
||||
val found = response.getCookie(defaultGroupCookieName)
|
||||
|
||||
assertNotNull(found)
|
||||
|
@ -290,57 +290,57 @@ class GroupServiceTest :
|
|||
|
||||
@Test
|
||||
override fun `save(dto) calls and returns save() with the created entity`() {
|
||||
withBaseSaveDtoTest(entity, entitySaveDto, service)
|
||||
withBaseSaveDtoTest(entity, entitySaveDto, logic)
|
||||
}
|
||||
|
||||
// update()
|
||||
|
||||
@Test
|
||||
override fun `update(dto) calls and returns update() with the created entity`() =
|
||||
withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() })
|
||||
withBaseUpdateDtoTest(entity, entityUpdateDto, logic, { any() })
|
||||
}
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class UserUserDetailsServiceTest {
|
||||
private val userService: UserService = mock()
|
||||
private val service = spy(UserDetailsServiceImpl(userService))
|
||||
class UserUserDetailsLogicTest {
|
||||
private val userLogic: UserLogic = mock()
|
||||
private val logic = spy(DefaultUserDetailsLogic(userLogic))
|
||||
|
||||
private val user = user(id = 0L)
|
||||
|
||||
@BeforeEach
|
||||
fun beforeEach() {
|
||||
reset(userService, service)
|
||||
reset(userLogic, logic)
|
||||
}
|
||||
|
||||
// loadUserByUsername()
|
||||
|
||||
@Test
|
||||
fun `loadUserByUsername() calls loadUserByUserId() with the given username as an id`() {
|
||||
whenever(userService.getById(eq(user.id), any(), any())).doReturn(user)
|
||||
whenever(userLogic.getById(eq(user.id), any(), any())).doReturn(user)
|
||||
doReturn(UserDetails(user(id = user.id, plainPassword = user.password)))
|
||||
.whenever(service).loadUserById(user.id)
|
||||
.whenever(logic).loadUserById(user.id)
|
||||
|
||||
service.loadUserByUsername(user.id.toString())
|
||||
logic.loadUserByUsername(user.id.toString())
|
||||
|
||||
verify(service).loadUserById(eq(user.id), any())
|
||||
verify(logic).loadUserById(eq(user.id), any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `loadUserByUsername() throws UsernameNotFoundException when no user with the given id exists`() {
|
||||
whenever(userService.getById(eq(user.id), any(), any())).doThrow(
|
||||
whenever(userLogic.getById(eq(user.id), any(), any())).doThrow(
|
||||
userIdNotFoundException(user.id)
|
||||
)
|
||||
|
||||
assertThrows<UsernameNotFoundException> { service.loadUserByUsername(user.id.toString()) }
|
||||
assertThrows<UsernameNotFoundException> { logic.loadUserByUsername(user.id.toString()) }
|
||||
}
|
||||
|
||||
// loadUserByUserId
|
||||
|
||||
@Test
|
||||
fun `loadUserByUserId() returns an User corresponding to the user with the given id`() {
|
||||
whenever(userService.getById(eq(user.id), any(), any())).doReturn(user)
|
||||
whenever(userLogic.getById(eq(user.id), any(), any())).doReturn(user)
|
||||
|
||||
val found = service.loadUserById(user.id)
|
||||
val found = logic.loadUserById(user.id)
|
||||
|
||||
assertEquals(user.id, found.username.toLong())
|
||||
assertEquals(user.password, found.password)
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
|
@ -10,11 +10,16 @@ import kotlin.test.assertFalse
|
|||
import kotlin.test.assertTrue
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class CompanyServiceTest :
|
||||
AbstractExternalNamedModelServiceTest<Company, CompanySaveDto, CompanyUpdateDto, CompanyService, CompanyRepository>() {
|
||||
private val recipeService: RecipeService = mock()
|
||||
class CompanyLogicTest :
|
||||
AbstractExternalNamedModelServiceTest<Company, CompanySaveDto, CompanyUpdateDto, CompanyLogic, CompanyRepository>() {
|
||||
private val recipeLogic: RecipeLogic = mock()
|
||||
override val repository: CompanyRepository = mock()
|
||||
override val service: CompanyService = spy(CompanyServiceImpl(repository, recipeService))
|
||||
override val logic: CompanyLogic = spy(
|
||||
DefaultCompanyLogic(
|
||||
repository,
|
||||
recipeLogic
|
||||
)
|
||||
)
|
||||
|
||||
override val entity: Company = company(id = 0L, name = "company")
|
||||
override val anotherEntity: Company = company(id = 1L, name = "another company")
|
||||
|
@ -24,7 +29,7 @@ class CompanyServiceTest :
|
|||
|
||||
@AfterEach
|
||||
override fun afterEach() {
|
||||
reset(recipeService)
|
||||
reset(recipeLogic)
|
||||
super.afterEach()
|
||||
}
|
||||
|
||||
|
@ -32,18 +37,18 @@ class CompanyServiceTest :
|
|||
|
||||
@Test
|
||||
fun `isLinkedToRecipes() returns true when a given company is linked to one or more recipes`() {
|
||||
whenever(recipeService.existsByCompany(entity)).doReturn(true)
|
||||
whenever(recipeLogic.existsByCompany(entity)).doReturn(true)
|
||||
|
||||
val found = service.isLinkedToRecipes(entity)
|
||||
val found = logic.isLinkedToRecipes(entity)
|
||||
|
||||
assertTrue(found)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isLinkedToRecipes() returns false when a given company is not linked to any recipe`() {
|
||||
whenever(recipeService.existsByCompany(entity)).doReturn(false)
|
||||
whenever(recipeLogic.existsByCompany(entity)).doReturn(false)
|
||||
|
||||
val found = service.isLinkedToRecipes(entity)
|
||||
val found = logic.isLinkedToRecipes(entity)
|
||||
|
||||
assertFalse(found)
|
||||
}
|
||||
|
@ -52,14 +57,14 @@ class CompanyServiceTest :
|
|||
|
||||
@Test
|
||||
override fun `save(dto) calls and returns save() with the created entity`() {
|
||||
withBaseSaveDtoTest(entity, entitySaveDto, service)
|
||||
withBaseSaveDtoTest(entity, entitySaveDto, logic)
|
||||
}
|
||||
|
||||
// update()
|
||||
|
||||
@Test
|
||||
override fun `update(dto) calls and returns update() with the created entity`() =
|
||||
withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() })
|
||||
withBaseUpdateDtoTest(entity, entityUpdateDto, logic, { any() })
|
||||
|
||||
// delete()
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties
|
||||
import dev.fyloz.colorrecipesexplorer.logic.config.CONFIGURATION_FORMATTED_LIST_DELIMITER
|
||||
import dev.fyloz.colorrecipesexplorer.logic.config.ConfigurationSource
|
||||
import dev.fyloz.colorrecipesexplorer.logic.config.DefaultConfigurationLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.ResourceFileLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.WriteableFileLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.service.config.CONFIGURATION_FORMATTED_LIST_DELIMITER
|
||||
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationServiceImpl
|
||||
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationSource
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.ResourceFileService
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.WriteableFileService
|
||||
import dev.fyloz.colorrecipesexplorer.utils.encrypt
|
||||
import io.mockk.*
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
|
@ -18,20 +18,19 @@ import kotlin.test.assertEquals
|
|||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ConfigurationServiceTest {
|
||||
private val fileService = mockk<WriteableFileService>()
|
||||
private val resourceFileService = mockk<ResourceFileService>()
|
||||
class ConfigurationLogicTest {
|
||||
private val fileLogic = mockk<WriteableFileLogic>()
|
||||
private val resourceFileLogic = mockk<ResourceFileLogic>()
|
||||
private val configurationSource = mockk<ConfigurationSource>()
|
||||
private val securityProperties = mockk<CreSecurityProperties> {
|
||||
every { configSalt } returns "d32270943af7e1cc"
|
||||
}
|
||||
private val service = spyk(
|
||||
ConfigurationServiceImpl(
|
||||
fileService,
|
||||
resourceFileService,
|
||||
private val logic = spyk(
|
||||
DefaultConfigurationLogic(
|
||||
fileLogic,
|
||||
resourceFileLogic,
|
||||
configurationSource,
|
||||
securityProperties,
|
||||
mockk()
|
||||
securityProperties
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -44,17 +43,17 @@ class ConfigurationServiceTest {
|
|||
|
||||
@Test
|
||||
fun `getAll() gets the Configuration of each ConfigurationType`() {
|
||||
every { service.get(any<ConfigurationType>()) } answers { throw ConfigurationNotSetException(this.args[0] as ConfigurationType) }
|
||||
every { logic.get(any<ConfigurationType>()) } answers { throw ConfigurationNotSetException(this.args[0] as ConfigurationType) }
|
||||
|
||||
service.getAll()
|
||||
logic.getAll()
|
||||
|
||||
verify {
|
||||
service.getAll()
|
||||
logic.getAll()
|
||||
ConfigurationType.values().forEach {
|
||||
service.get(it)
|
||||
logic.get(it)
|
||||
}
|
||||
}
|
||||
confirmVerified(service)
|
||||
confirmVerified(logic)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -65,15 +64,15 @@ class ConfigurationServiceTest {
|
|||
ConfigurationType.INSTANCE_ICON_SET
|
||||
)
|
||||
|
||||
every { service.get(match<ConfigurationType> { it in unsetConfigurationTypes }) } answers {
|
||||
every { logic.get(match<ConfigurationType> { it in unsetConfigurationTypes }) } answers {
|
||||
throw ConfigurationNotSetException(this.firstArg() as ConfigurationType)
|
||||
}
|
||||
every { service.get(match<ConfigurationType> { it !in unsetConfigurationTypes }) } answers {
|
||||
every { logic.get(match<ConfigurationType> { it !in unsetConfigurationTypes }) } answers {
|
||||
val type = firstArg<ConfigurationType>()
|
||||
configuration(type, type.key)
|
||||
}
|
||||
|
||||
val found = service.getAll()
|
||||
val found = logic.getAll()
|
||||
|
||||
assertFalse {
|
||||
found.any {
|
||||
|
@ -82,12 +81,12 @@ class ConfigurationServiceTest {
|
|||
}
|
||||
|
||||
verify {
|
||||
service.getAll()
|
||||
logic.getAll()
|
||||
ConfigurationType.values().forEach {
|
||||
service.get(it)
|
||||
logic.get(it)
|
||||
}
|
||||
}
|
||||
confirmVerified(service)
|
||||
confirmVerified(logic)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -101,24 +100,24 @@ class ConfigurationServiceTest {
|
|||
.map { it.key }
|
||||
.reduce { acc, s -> "$acc$CONFIGURATION_FORMATTED_LIST_DELIMITER$s" }
|
||||
|
||||
every { service.get(any<String>()) } answers {
|
||||
every { logic.get(any<String>()) } answers {
|
||||
val key = firstArg<String>()
|
||||
configuration(key.toConfigurationType(), key)
|
||||
}
|
||||
|
||||
val found = service.getAll(formattedKeyList)
|
||||
val found = logic.getAll(formattedKeyList)
|
||||
|
||||
assertTrue {
|
||||
found.all { it.type in configurationTypes }
|
||||
}
|
||||
|
||||
verify {
|
||||
service.getAll(formattedKeyList)
|
||||
logic.getAll(formattedKeyList)
|
||||
configurationTypes.forEach {
|
||||
service.get(it.key)
|
||||
logic.get(it.key)
|
||||
}
|
||||
}
|
||||
confirmVerified(service)
|
||||
confirmVerified(logic)
|
||||
}
|
||||
|
||||
// get()
|
||||
|
@ -128,18 +127,18 @@ class ConfigurationServiceTest {
|
|||
val type = ConfigurationType.INSTANCE_ICON_SET
|
||||
val key = type.key
|
||||
|
||||
every { service.get(type) } answers {
|
||||
every { logic.get(type) } answers {
|
||||
val type = firstArg<ConfigurationType>()
|
||||
configuration(type, type.key)
|
||||
}
|
||||
|
||||
service.get(key)
|
||||
logic.get(key)
|
||||
|
||||
verify {
|
||||
service.get(key)
|
||||
service.get(type)
|
||||
logic.get(key)
|
||||
logic.get(type)
|
||||
}
|
||||
confirmVerified(service)
|
||||
confirmVerified(logic)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -149,7 +148,7 @@ class ConfigurationServiceTest {
|
|||
|
||||
every { configurationSource.get(type) } returns configuration
|
||||
|
||||
val found = service.get(type)
|
||||
val found = logic.get(type)
|
||||
|
||||
assertEquals(configuration, found)
|
||||
}
|
||||
|
@ -160,12 +159,12 @@ class ConfigurationServiceTest {
|
|||
|
||||
every { configurationSource.get(type) } returns null
|
||||
|
||||
with(assertThrows<ConfigurationNotSetException> { service.get(type) }) {
|
||||
with(assertThrows<ConfigurationNotSetException> { logic.get(type) }) {
|
||||
assertEquals(type, this.type)
|
||||
}
|
||||
|
||||
verify {
|
||||
service.get(type)
|
||||
logic.get(type)
|
||||
configurationSource.get(type)
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +173,7 @@ class ConfigurationServiceTest {
|
|||
fun `get(type) throws InvalidConfigurationKeyException when the given ConfigurationType is encryption salt`() {
|
||||
val type = ConfigurationType.GENERATED_ENCRYPTION_SALT
|
||||
|
||||
assertThrows<InvalidConfigurationKeyException> { service.get(type) }
|
||||
assertThrows<InvalidConfigurationKeyException> { logic.get(type) }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -187,7 +186,7 @@ class ConfigurationServiceTest {
|
|||
|
||||
every { configurationSource.get(type) } returns configuration
|
||||
|
||||
val found = service.get(type)
|
||||
val found = logic.get(type)
|
||||
|
||||
assertTrue { found is SecureConfiguration }
|
||||
}
|
||||
|
@ -200,9 +199,9 @@ class ConfigurationServiceTest {
|
|||
content = "content"
|
||||
)
|
||||
|
||||
every { service.get(type) } returns configuration
|
||||
every { logic.get(type) } returns configuration
|
||||
|
||||
val found = service.getContent(type)
|
||||
val found = logic.getContent(type)
|
||||
|
||||
assertEquals(configuration.content, found)
|
||||
}
|
||||
|
@ -212,9 +211,9 @@ class ConfigurationServiceTest {
|
|||
val type = ConfigurationType.DATABASE_PASSWORD
|
||||
val configuration = secureConfiguration(type)
|
||||
|
||||
every { service.get(type) } returns configuration
|
||||
every { logic.get(type) } returns configuration
|
||||
|
||||
assertThrows<UnsupportedOperationException> { service.getContent(type) }
|
||||
assertThrows<UnsupportedOperationException> { logic.getContent(type) }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -228,7 +227,7 @@ class ConfigurationServiceTest {
|
|||
|
||||
every { configurationSource.get(type) } returns configuration
|
||||
|
||||
val found = service.getSecure(type)
|
||||
val found = logic.getSecure(type)
|
||||
|
||||
assertEquals(content, found)
|
||||
}
|
||||
|
@ -237,7 +236,7 @@ class ConfigurationServiceTest {
|
|||
fun `getSecure(type) throws UnsupportedOperationException when configuration is not secure`() {
|
||||
val type = ConfigurationType.INSTANCE_NAME
|
||||
|
||||
assertThrows<UnsupportedOperationException> { service.getSecure(type) }
|
||||
assertThrows<UnsupportedOperationException> { logic.getSecure(type) }
|
||||
}
|
||||
|
||||
private fun getConfiguredImageTest(
|
||||
|
@ -247,9 +246,9 @@ class ConfigurationServiceTest {
|
|||
) {
|
||||
val resource = mockk<Resource>()
|
||||
val configuration = configuration(configurationType, imageSet.toString())
|
||||
val imageService = if (imageSet) fileService else resourceFileService
|
||||
val imageService = if (imageSet) fileLogic else resourceFileLogic
|
||||
|
||||
every { service.get(configurationType) } returns configuration
|
||||
every { logic.get(configurationType) } returns configuration
|
||||
every { imageService.read(any()) } returns resource
|
||||
|
||||
test(resource)
|
||||
|
@ -258,7 +257,7 @@ class ConfigurationServiceTest {
|
|||
@Test
|
||||
fun `getConfiguredIcon() gets icon from resources when INSTANCE_ICON_SET configuration is false`() {
|
||||
getConfiguredImageTest(ConfigurationType.INSTANCE_ICON_SET, false) { resource ->
|
||||
val found = service.getConfiguredIcon()
|
||||
val found = logic.getConfiguredIcon()
|
||||
|
||||
assertEquals(resource, found)
|
||||
}
|
||||
|
@ -267,7 +266,7 @@ class ConfigurationServiceTest {
|
|||
@Test
|
||||
fun `getConfiguredIcon() gets icon from files when INSTANCE_ICON_SET configuration is true`() {
|
||||
getConfiguredImageTest(ConfigurationType.INSTANCE_ICON_SET, true) { resource ->
|
||||
val found = service.getConfiguredIcon()
|
||||
val found = logic.getConfiguredIcon()
|
||||
|
||||
assertEquals(resource, found)
|
||||
}
|
||||
|
@ -276,7 +275,7 @@ class ConfigurationServiceTest {
|
|||
@Test
|
||||
fun `getConfiguredLogo() gets logo from resources when INSTANCE_LOGO_SET is false`() {
|
||||
getConfiguredImageTest(ConfigurationType.INSTANCE_LOGO_SET, false) { resource ->
|
||||
val found = service.getConfiguredLogo()
|
||||
val found = logic.getConfiguredLogo()
|
||||
|
||||
assertEquals(resource, found)
|
||||
}
|
||||
|
@ -285,7 +284,7 @@ class ConfigurationServiceTest {
|
|||
@Test
|
||||
fun `getConfiguredLogo() gets logo from files when INSTANCE_LOGO_SET is true`() {
|
||||
getConfiguredImageTest(ConfigurationType.INSTANCE_LOGO_SET, true) { resource ->
|
||||
val found = service.getConfiguredLogo()
|
||||
val found = logic.getConfiguredLogo()
|
||||
|
||||
assertEquals(resource, found)
|
||||
}
|
||||
|
@ -297,7 +296,7 @@ class ConfigurationServiceTest {
|
|||
|
||||
every { configurationSource.set(any<Configuration>()) } just runs
|
||||
|
||||
service.set(configuration)
|
||||
logic.set(configuration)
|
||||
|
||||
verify {
|
||||
configurationSource.set(configuration)
|
||||
|
@ -316,7 +315,7 @@ class ConfigurationServiceTest {
|
|||
every { configurationSource.set(any<Configuration>()) } just runs
|
||||
every { content.encrypt(any(), any()) } returns encryptedContent
|
||||
|
||||
service.set(configuration)
|
||||
logic.set(configuration)
|
||||
|
||||
verify {
|
||||
configurationSource.set(match<Configuration> {
|
||||
|
@ -328,8 +327,8 @@ class ConfigurationServiceTest {
|
|||
private fun setConfiguredImageTest(test: (MultipartFile) -> Unit) {
|
||||
val file = mockk<MultipartFile>()
|
||||
|
||||
every { service.set(any<Configuration>()) } just runs
|
||||
every { fileService.write(any<MultipartFile>(), any(), any()) } just runs
|
||||
every { logic.set(any<Configuration>()) } just runs
|
||||
every { fileLogic.write(any<MultipartFile>(), any(), any()) } just runs
|
||||
|
||||
test(file)
|
||||
}
|
||||
|
@ -337,10 +336,10 @@ class ConfigurationServiceTest {
|
|||
@Test
|
||||
fun `setConfiguredIcon() sets icon in files`() {
|
||||
setConfiguredImageTest { file ->
|
||||
service.setConfiguredIcon(file)
|
||||
logic.setConfiguredIcon(file)
|
||||
|
||||
verify {
|
||||
fileService.write(file, any(), true)
|
||||
fileLogic.write(file, any(), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -350,10 +349,10 @@ class ConfigurationServiceTest {
|
|||
val type = ConfigurationType.INSTANCE_ICON_SET
|
||||
|
||||
setConfiguredImageTest { file ->
|
||||
service.setConfiguredIcon(file)
|
||||
logic.setConfiguredIcon(file)
|
||||
|
||||
verify {
|
||||
service.set(match<Configuration> {
|
||||
logic.set(match<Configuration> {
|
||||
it.key == type.key && it.content == true.toString()
|
||||
})
|
||||
}
|
||||
|
@ -363,10 +362,10 @@ class ConfigurationServiceTest {
|
|||
@Test
|
||||
fun `setConfiguredLogo() sets logo in files`() {
|
||||
setConfiguredImageTest { file ->
|
||||
service.setConfiguredLogo(file)
|
||||
logic.setConfiguredLogo(file)
|
||||
|
||||
verify {
|
||||
fileService.write(file, any(), true)
|
||||
fileLogic.write(file, any(), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,10 +375,10 @@ class ConfigurationServiceTest {
|
|||
val type = ConfigurationType.INSTANCE_LOGO_SET
|
||||
|
||||
setConfiguredImageTest { file ->
|
||||
service.setConfiguredLogo(file)
|
||||
logic.setConfiguredLogo(file)
|
||||
|
||||
verify {
|
||||
service.set(match<Configuration> {
|
||||
logic.set(match<Configuration> {
|
||||
it.key == type.key && it.content == true.toString()
|
||||
})
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
|
@ -10,14 +10,14 @@ import kotlin.test.assertEquals
|
|||
import kotlin.test.assertTrue
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class InventoryServiceTest {
|
||||
private val materialService: MaterialService = mock()
|
||||
private val mixService: MixService = mock()
|
||||
private val service = spy(InventoryServiceImpl(materialService, mixService))
|
||||
class InventoryLogicTest {
|
||||
private val materialLogic: MaterialLogic = mock()
|
||||
private val mixLogic: MixLogic = mock()
|
||||
private val logic = spy(DefaultInventoryLogic(materialLogic, mixLogic))
|
||||
|
||||
@AfterEach
|
||||
fun afterEach() {
|
||||
reset(materialService, service)
|
||||
reset(materialLogic, logic)
|
||||
}
|
||||
|
||||
// add()
|
||||
|
@ -32,13 +32,13 @@ class InventoryServiceTest {
|
|||
)
|
||||
val storedQuantity = 2000f
|
||||
|
||||
doAnswer { storedQuantity + (it.arguments[0] as MaterialQuantityDto).quantity }.whenever(service)
|
||||
doAnswer { storedQuantity + (it.arguments[0] as MaterialQuantityDto).quantity }.whenever(logic)
|
||||
.add(any<MaterialQuantityDto>())
|
||||
|
||||
val found = service.add(materialQuantities)
|
||||
val found = logic.add(materialQuantities)
|
||||
|
||||
materialQuantities.forEach {
|
||||
verify(service).add(it)
|
||||
verify(logic).add(it)
|
||||
assertTrue { found.any { updated -> updated.material == it.material && updated.quantity == storedQuantity + it.quantity } }
|
||||
}
|
||||
}
|
||||
|
@ -47,11 +47,11 @@ class InventoryServiceTest {
|
|||
fun `add(materialQuantity) updates material's quantity`() {
|
||||
withGivenQuantities(0f, 1000f) {
|
||||
val updatedQuantity = it + this.quantity
|
||||
whenever(materialService.updateQuantity(any(), eq(this.quantity))).doReturn(updatedQuantity)
|
||||
whenever(materialLogic.updateQuantity(any(), eq(this.quantity))).doReturn(updatedQuantity)
|
||||
|
||||
val found = service.add(this)
|
||||
val found = logic.add(this)
|
||||
|
||||
verify(materialService).updateQuantity(
|
||||
verify(materialLogic).updateQuantity(
|
||||
argThat { this.id == this@withGivenQuantities.material },
|
||||
eq(this.quantity)
|
||||
)
|
||||
|
@ -78,16 +78,16 @@ class InventoryServiceTest {
|
|||
1L to 750f
|
||||
)
|
||||
|
||||
whenever(mixService.getById(mix.id!!)).doReturn(mix)
|
||||
whenever(mixLogic.getById(mix.id!!)).doReturn(mix)
|
||||
doAnswer {
|
||||
(it.arguments[0] as Collection<MaterialQuantityDto>).map { materialQuantity ->
|
||||
materialQuantityDto(materialId = materialQuantity.material, quantity = 0f)
|
||||
}
|
||||
}.whenever(service).deduct(any<Collection<MaterialQuantityDto>>())
|
||||
}.whenever(logic).deduct(any<Collection<MaterialQuantityDto>>())
|
||||
|
||||
val found = service.deductMix(mixRatio)
|
||||
val found = logic.deductMix(mixRatio)
|
||||
|
||||
verify(service).deduct(argThat<Collection<MaterialQuantityDto>> {
|
||||
verify(logic).deduct(argThat<Collection<MaterialQuantityDto>> {
|
||||
this.all { it.quantity == expectedQuantities[it.material] }
|
||||
})
|
||||
|
||||
|
@ -106,13 +106,13 @@ class InventoryServiceTest {
|
|||
)
|
||||
val storedQuantity = 5000f
|
||||
|
||||
doAnswer { storedQuantity - (it.arguments[0] as MaterialQuantityDto).quantity }.whenever(service)
|
||||
doAnswer { storedQuantity - (it.arguments[0] as MaterialQuantityDto).quantity }.whenever(logic)
|
||||
.deduct(any<MaterialQuantityDto>())
|
||||
|
||||
val found = service.deduct(materialQuantities)
|
||||
val found = logic.deduct(materialQuantities)
|
||||
|
||||
materialQuantities.forEach {
|
||||
verify(service).deduct(it)
|
||||
verify(logic).deduct(it)
|
||||
assertTrue { found.any { updated -> updated.material == it.material && updated.quantity == storedQuantity - it.quantity } }
|
||||
}
|
||||
}
|
||||
|
@ -131,18 +131,18 @@ class InventoryServiceTest {
|
|||
withGivenQuantities(inventoryQuantity, it)
|
||||
}
|
||||
|
||||
assertThrows<MultiplesNotEnoughInventoryException> { service.deduct(materialQuantities) }
|
||||
assertThrows<MultiplesNotEnoughInventoryException> { logic.deduct(materialQuantities) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `deduct(materialQuantity) updates material's quantity`() {
|
||||
withGivenQuantities(5000f, 1000f) {
|
||||
val updatedQuantity = it - this.quantity
|
||||
whenever(materialService.updateQuantity(any(), eq(-this.quantity))).doReturn(updatedQuantity)
|
||||
whenever(materialLogic.updateQuantity(any(), eq(-this.quantity))).doReturn(updatedQuantity)
|
||||
|
||||
val found = service.deduct(this)
|
||||
val found = logic.deduct(this)
|
||||
|
||||
verify(materialService).updateQuantity(
|
||||
verify(materialLogic).updateQuantity(
|
||||
argThat { this.id == this@withGivenQuantities.material },
|
||||
eq(-this.quantity)
|
||||
)
|
||||
|
@ -153,7 +153,7 @@ class InventoryServiceTest {
|
|||
@Test
|
||||
fun `deduct(materialQuantity) throws NotEnoughInventoryException when there is not enough inventory of the given material`() {
|
||||
withGivenQuantities(0f, 1000f) {
|
||||
assertThrows<NotEnoughInventoryException> { service.deduct(this) }
|
||||
assertThrows<NotEnoughInventoryException> { logic.deduct(this) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ class InventoryServiceTest {
|
|||
) {
|
||||
val material = material(id = materialQuantity.material, inventoryQuantity = stored)
|
||||
|
||||
whenever(materialService.getById(material.id!!)).doReturn(material)
|
||||
whenever(materialLogic.getById(material.id!!)).doReturn(material)
|
||||
|
||||
materialQuantity.test(stored)
|
||||
}
|
|
@ -1,26 +1,25 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties
|
||||
import dev.fyloz.colorrecipesexplorer.logic.users.DefaultJwtLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.users.jwtClaimUser
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.UserDetails
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.UserOutputDto
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.toOutputDto
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.user
|
||||
import dev.fyloz.colorrecipesexplorer.service.users.JwtServiceImpl
|
||||
import dev.fyloz.colorrecipesexplorer.service.users.jwtClaimUser
|
||||
import dev.fyloz.colorrecipesexplorer.utils.base64encode
|
||||
import dev.fyloz.colorrecipesexplorer.utils.isAround
|
||||
import io.jsonwebtoken.Jwts
|
||||
import io.jsonwebtoken.jackson.io.JacksonDeserializer
|
||||
import io.mockk.spyk
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.Instant
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class JwtServiceTest {
|
||||
class JwtLogicTest {
|
||||
private val objectMapper = jacksonObjectMapper()
|
||||
private val securityProperties = CreSecurityProperties().apply {
|
||||
jwtSecret = "XRRm7OflmFuCrOB2Xvmfsercih9DCKom"
|
||||
|
@ -33,7 +32,7 @@ class JwtServiceTest {
|
|||
.build()
|
||||
}
|
||||
|
||||
private val jwtService = spyk(JwtServiceImpl(objectMapper, securityProperties))
|
||||
private val jwtService = spyk(DefaultJwtLogic(objectMapper, securityProperties))
|
||||
|
||||
private val user = user()
|
||||
private val userOutputDto = user.toOutputDto()
|
|
@ -1,10 +1,10 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.WriteableFileLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.repository.MaterialRepository
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.WriteableFileService
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
|
@ -15,15 +15,15 @@ import kotlin.test.assertFalse
|
|||
import kotlin.test.assertTrue
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class MaterialServiceTest :
|
||||
AbstractExternalNamedModelServiceTest<Material, MaterialSaveDto, MaterialUpdateDto, MaterialService, MaterialRepository>() {
|
||||
class MaterialLogicTest :
|
||||
AbstractExternalNamedModelServiceTest<Material, MaterialSaveDto, MaterialUpdateDto, MaterialLogic, MaterialRepository>() {
|
||||
override val repository: MaterialRepository = mock()
|
||||
private val recipeService: RecipeService = mock()
|
||||
private val mixService: MixService = mock()
|
||||
private val materialTypeService: MaterialTypeService = mock()
|
||||
private val fileService: WriteableFileService = mock()
|
||||
override val service: MaterialService =
|
||||
spy(MaterialServiceImpl(repository, recipeService, mixService, materialTypeService, fileService, mock()))
|
||||
private val recipeService: RecipeLogic = mock()
|
||||
private val mixService: MixLogic = mock()
|
||||
private val materialTypeService: MaterialTypeLogic = mock()
|
||||
private val fileService: WriteableFileLogic = mock()
|
||||
override val logic: MaterialLogic =
|
||||
spy(DefaultMaterialLogic(repository, recipeService, mixService, materialTypeService, fileService, mock()))
|
||||
|
||||
override val entity: Material = material(id = 0L, name = "material")
|
||||
private val entityOutput = materialOutputDto(entity)
|
||||
|
@ -46,7 +46,7 @@ class MaterialServiceTest :
|
|||
fun `existsByMaterialType() returns true when a material with the given material type exists in the repository`() {
|
||||
whenever(repository.existsByMaterialType(materialType)).doReturn(true)
|
||||
|
||||
val found = service.existsByMaterialType(materialType)
|
||||
val found = logic.existsByMaterialType(materialType)
|
||||
|
||||
assertTrue(found)
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ class MaterialServiceTest :
|
|||
fun `existsByMaterialType() returns false when no material with the given material type exists in the repository`() {
|
||||
whenever(repository.existsByMaterialType(materialType)).doReturn(false)
|
||||
|
||||
val found = service.existsByMaterialType(materialType)
|
||||
val found = logic.existsByMaterialType(materialType)
|
||||
|
||||
assertFalse(found)
|
||||
}
|
||||
|
@ -65,9 +65,9 @@ class MaterialServiceTest :
|
|||
@Test
|
||||
fun `hasSimdut() returns false when simdutService_exists() returns false`() {
|
||||
whenever(fileService.exists(any())).doReturn(false)
|
||||
doReturn(entity).whenever(service).getById(entity.id!!)
|
||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||
|
||||
val found = service.hasSimdut(entity)
|
||||
val found = logic.hasSimdut(entity)
|
||||
|
||||
assertFalse(found)
|
||||
}
|
||||
|
@ -75,9 +75,9 @@ class MaterialServiceTest :
|
|||
@Test
|
||||
fun `hasSimdut() returns true when simdutService_exists() returns true`() {
|
||||
whenever(fileService.exists(any())).doReturn(true)
|
||||
doReturn(entity).whenever(service).getById(entity.id!!)
|
||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||
|
||||
val found = service.hasSimdut(entity)
|
||||
val found = logic.hasSimdut(entity)
|
||||
|
||||
assertTrue(found)
|
||||
}
|
||||
|
@ -90,9 +90,9 @@ class MaterialServiceTest :
|
|||
val mixTypeMaterialOutput = materialOutputDto(mixTypeMaterial)
|
||||
val materialList = listOf(entity, mixTypeMaterial)
|
||||
|
||||
doReturn(materialList).whenever(service).getAll()
|
||||
doReturn(materialList).whenever(logic).getAll()
|
||||
|
||||
val found = service.getAllNotMixType()
|
||||
val found = logic.getAllNotMixType()
|
||||
|
||||
assertTrue(found.contains(entityOutput))
|
||||
assertFalse(found.contains(mixTypeMaterialOutput))
|
||||
|
@ -102,15 +102,15 @@ class MaterialServiceTest :
|
|||
|
||||
@Test
|
||||
fun `save() throws AlreadyExistsException when a material with the given name exists in the repository`() {
|
||||
doReturn(true).whenever(service).existsByName(entity.name)
|
||||
doReturn(true).whenever(logic).existsByName(entity.name)
|
||||
|
||||
assertThrows<AlreadyExistsException> { service.save(entity) }
|
||||
assertThrows<AlreadyExistsException> { logic.save(entity) }
|
||||
.assertErrorCode("name")
|
||||
}
|
||||
|
||||
@Test
|
||||
override fun `save(dto) calls and returns save() with the created entity`() {
|
||||
withBaseSaveDtoTest(entity, entitySaveDto, service, { any() })
|
||||
withBaseSaveDtoTest(entity, entitySaveDto, logic, { any() })
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -119,9 +119,9 @@ class MaterialServiceTest :
|
|||
val materialSaveDto = spy(materialSaveDto(simdutFile = mockMultipartFile))
|
||||
|
||||
doReturn(false).whenever(mockMultipartFile).isEmpty
|
||||
doReturn(entity).whenever(service).save(any<Material>())
|
||||
doReturn(entity).whenever(logic).save(any<Material>())
|
||||
|
||||
service.save(materialSaveDto)
|
||||
logic.save(materialSaveDto)
|
||||
|
||||
verify(fileService).write(mockMultipartFile, entity.simdutFilePath, false)
|
||||
}
|
||||
|
@ -134,9 +134,9 @@ class MaterialServiceTest :
|
|||
val anotherMaterial = material(id = 1L, name = "name")
|
||||
|
||||
whenever(repository.findByName(material.name)).doReturn(anotherMaterial)
|
||||
doReturn(entity).whenever(service).getById(material.id!!)
|
||||
doReturn(entity).whenever(logic).getById(material.id!!)
|
||||
|
||||
assertThrows<AlreadyExistsException> { service.update(material) }
|
||||
assertThrows<AlreadyExistsException> { logic.update(material) }
|
||||
.assertErrorCode("name")
|
||||
}
|
||||
|
||||
|
@ -145,11 +145,11 @@ class MaterialServiceTest :
|
|||
val mockSimdutFile = MockMultipartFile("simdut", byteArrayOf(1, 2, 3, 4, 5))
|
||||
val materialUpdateDto = spy(materialUpdateDto(id = 0L, simdutFile = mockSimdutFile))
|
||||
|
||||
doReturn(entity).whenever(service).getById(any())
|
||||
doReturn(entity).whenever(service).update(any<Material>())
|
||||
doReturn(entity).whenever(logic).getById(any())
|
||||
doReturn(entity).whenever(logic).update(any<Material>())
|
||||
doReturn(entity).whenever(materialUpdateDto).toEntity()
|
||||
|
||||
service.update(materialUpdateDto)
|
||||
logic.update(materialUpdateDto)
|
||||
|
||||
verify(fileService).write(mockSimdutFile, entity.simdutFilePath, true)
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ class MaterialServiceTest :
|
|||
val quantity = 1234f
|
||||
val totalQuantity = material.inventoryQuantity + quantity
|
||||
|
||||
val found = service.updateQuantity(material, quantity)
|
||||
val found = logic.updateQuantity(material, quantity)
|
||||
|
||||
verify(repository).updateInventoryQuantityById(material.id!!, totalQuantity)
|
||||
assertEquals(totalQuantity, found)
|
||||
|
@ -180,9 +180,9 @@ class MaterialServiceTest :
|
|||
recipe(id = 0L, mixes = mutableListOf(mix(mixType = mixType(id = 0L, material = mixTypeMaterial))))
|
||||
|
||||
whenever(recipeService.getById(recipe.id!!)).doReturn(recipe)
|
||||
doReturn(materials).whenever(service).getAll()
|
||||
doReturn(materials).whenever(logic).getAll()
|
||||
|
||||
val found = service.getAllForMixCreation(recipe.id!!)
|
||||
val found = logic.getAllForMixCreation(recipe.id!!)
|
||||
|
||||
assertTrue(materialOutputDto(normalMaterial) in found)
|
||||
assertTrue(materialOutputDto(mixTypeMaterial) in found)
|
||||
|
@ -202,9 +202,9 @@ class MaterialServiceTest :
|
|||
recipe.mixes.add(mix)
|
||||
|
||||
whenever(mixService.getById(mix.id!!)).doReturn(mix)
|
||||
doReturn(materials).whenever(service).getAll()
|
||||
doReturn(materials).whenever(logic).getAll()
|
||||
|
||||
val found = service.getAllForMixUpdate(mix.id!!)
|
||||
val found = logic.getAllForMixUpdate(mix.id!!)
|
||||
|
||||
assertTrue(materialOutputDto(normalMaterial) in found)
|
||||
assertTrue(materialOutputDto(mixTypeMaterial) in found)
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
||||
|
@ -16,11 +16,11 @@ import kotlin.test.assertFalse
|
|||
import kotlin.test.assertTrue
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class MaterialTypeServiceTest :
|
||||
AbstractExternalNamedModelServiceTest<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialTypeService, MaterialTypeRepository>() {
|
||||
class MaterialTypeLogicTest :
|
||||
AbstractExternalNamedModelServiceTest<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialTypeLogic, MaterialTypeRepository>() {
|
||||
override val repository: MaterialTypeRepository = mock()
|
||||
private val materialService: MaterialService = mock()
|
||||
override val service: MaterialTypeService = spy(MaterialTypeServiceImpl(repository, materialService))
|
||||
private val materialService: MaterialLogic = mock()
|
||||
override val logic: MaterialTypeLogic = spy(DefaultMaterialTypeLogic(repository, materialService))
|
||||
override val entity: MaterialType = materialType(id = 0L, name = "material type", prefix = "MAT")
|
||||
override val anotherEntity: MaterialType = materialType(id = 1L, name = "another material type", prefix = "AMT")
|
||||
override val entityWithEntityName: MaterialType = materialType(2L, name = entity.name, prefix = "EEN")
|
||||
|
@ -42,7 +42,7 @@ class MaterialTypeServiceTest :
|
|||
fun `existsByPrefix() returns true when a material type with the given prefix exists`() {
|
||||
whenever(repository.existsByPrefix(entity.prefix)).doReturn(true)
|
||||
|
||||
val found = service.existsByPrefix(entity.prefix)
|
||||
val found = logic.existsByPrefix(entity.prefix)
|
||||
|
||||
assertTrue(found)
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class MaterialTypeServiceTest :
|
|||
fun `existsByPrefix() returns false when no material type with the given prefix exists`() {
|
||||
whenever(repository.existsByPrefix(entity.prefix)).doReturn(false)
|
||||
|
||||
val found = service.existsByPrefix(entity.prefix)
|
||||
val found = logic.existsByPrefix(entity.prefix)
|
||||
|
||||
assertFalse(found)
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ class MaterialTypeServiceTest :
|
|||
fun `isUsedByMaterial() returns true when materialService_existsByMaterialType() returns true`() {
|
||||
whenever(materialService.existsByMaterialType(entity)).doReturn(true)
|
||||
|
||||
val found = service.isUsedByMaterial(entity)
|
||||
val found = logic.isUsedByMaterial(entity)
|
||||
|
||||
assertTrue(found)
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ class MaterialTypeServiceTest :
|
|||
fun `isUsedByMaterial() returns false when materialService_existsByMaterialType() returns false`() {
|
||||
whenever(materialService.existsByMaterialType(entity)).doReturn(false)
|
||||
|
||||
val found = service.isUsedByMaterial(entity)
|
||||
val found = logic.isUsedByMaterial(entity)
|
||||
|
||||
assertFalse(found)
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ class MaterialTypeServiceTest :
|
|||
fun `getAllSystemTypes() returns all system types`() {
|
||||
whenever(repository.findAllBySystemTypeIs(true)).doReturn(listOf(systemType, anotherSystemType))
|
||||
|
||||
val found = service.getAllSystemTypes()
|
||||
val found = logic.getAllSystemTypes()
|
||||
|
||||
assertTrue(found.contains(systemType))
|
||||
assertTrue(found.contains(anotherSystemType))
|
||||
|
@ -94,7 +94,7 @@ class MaterialTypeServiceTest :
|
|||
fun `getAllNonSystemTypes() returns all non system types`() {
|
||||
whenever(repository.findAllBySystemTypeIs(false)).doReturn(listOf(entity, anotherEntity))
|
||||
|
||||
val found = service.getAllNonSystemType()
|
||||
val found = logic.getAllNonSystemType()
|
||||
|
||||
assertTrue(found.contains(entity))
|
||||
assertTrue(found.contains(anotherEntity))
|
||||
|
@ -104,16 +104,16 @@ class MaterialTypeServiceTest :
|
|||
|
||||
@Test
|
||||
override fun `save(dto) calls and returns save() with the created entity`() {
|
||||
withBaseSaveDtoTest(entity, entitySaveDto, service)
|
||||
withBaseSaveDtoTest(entity, entitySaveDto, logic)
|
||||
}
|
||||
|
||||
// saveMaterialType()
|
||||
|
||||
@Test
|
||||
fun `saveMaterialType() throws AlreadyExistsException when a material type with the given prefix already exists`() {
|
||||
doReturn(true).whenever(service).existsByPrefix(entity.prefix)
|
||||
doReturn(true).whenever(logic).existsByPrefix(entity.prefix)
|
||||
|
||||
assertThrows<AlreadyExistsException> { service.save(entity) }
|
||||
assertThrows<AlreadyExistsException> { logic.save(entity) }
|
||||
.assertErrorCode("prefix")
|
||||
}
|
||||
|
||||
|
@ -121,16 +121,16 @@ class MaterialTypeServiceTest :
|
|||
|
||||
@Test
|
||||
override fun `update(dto) calls and returns update() with the created entity`() =
|
||||
withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() })
|
||||
withBaseUpdateDtoTest(entity, entityUpdateDto, logic, { any() })
|
||||
|
||||
override fun `update() saves in the repository and returns the updated value`() {
|
||||
whenever(repository.save(entity)).doReturn(entity)
|
||||
whenever(repository.findByName(entity.name)).doReturn(null)
|
||||
whenever(repository.findByPrefix(entity.prefix)).doReturn(null)
|
||||
doReturn(true).whenever(service).existsById(entity.id!!)
|
||||
doReturn(entity).whenever(service).getById(entity.id!!)
|
||||
doReturn(true).whenever(logic).existsById(entity.id!!)
|
||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||
|
||||
val found = service.update(entity)
|
||||
val found = logic.update(entity)
|
||||
|
||||
verify(repository).save(entity)
|
||||
assertEquals(entity, found)
|
||||
|
@ -139,20 +139,20 @@ class MaterialTypeServiceTest :
|
|||
override fun `update() throws NotFoundException when no entity with the given id exists in the repository`() {
|
||||
whenever(repository.findByName(entity.name)).doReturn(null)
|
||||
whenever(repository.findByPrefix(entity.prefix)).doReturn(null)
|
||||
doReturn(false).whenever(service).existsById(entity.id!!)
|
||||
doReturn(null).whenever(service).getById(entity.id!!)
|
||||
doReturn(false).whenever(logic).existsById(entity.id!!)
|
||||
doReturn(null).whenever(logic).getById(entity.id!!)
|
||||
|
||||
assertThrows<NotFoundException> { service.update(entity) }
|
||||
assertThrows<NotFoundException> { logic.update(entity) }
|
||||
.assertErrorCode()
|
||||
}
|
||||
|
||||
override fun `update() throws AlreadyExistsException when an entity with the updated name exists`() {
|
||||
whenever(repository.findByName(entity.name)).doReturn(entityWithEntityName)
|
||||
whenever(repository.findByPrefix(entity.prefix)).doReturn(null)
|
||||
doReturn(true).whenever(service).existsById(entity.id!!)
|
||||
doReturn(entity).whenever(service).getById(entity.id!!)
|
||||
doReturn(true).whenever(logic).existsById(entity.id!!)
|
||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||
|
||||
assertThrows<AlreadyExistsException> { service.update(entity) }
|
||||
assertThrows<AlreadyExistsException> { logic.update(entity) }
|
||||
.assertErrorCode("name")
|
||||
}
|
||||
|
||||
|
@ -160,9 +160,9 @@ class MaterialTypeServiceTest :
|
|||
fun `update() throws AlreadyExistsException when an entity with the updated prefix exists`() {
|
||||
val anotherMaterialType = materialType(prefix = entity.prefix)
|
||||
whenever(repository.findByPrefix(entity.prefix)).doReturn(anotherMaterialType)
|
||||
doReturn(entity).whenever(service).getById(entity.id!!)
|
||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||
|
||||
assertThrows<AlreadyExistsException> { service.update(entity) }
|
||||
assertThrows<AlreadyExistsException> { logic.update(entity) }
|
||||
.assertErrorCode("prefix")
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ class MaterialTypeServiceTest :
|
|||
fun `update() throws CannotUpdateException when updating a system material type`() {
|
||||
whenever(repository.existsByIdAndSystemTypeIsTrue(systemType.id!!)).doReturn(true)
|
||||
|
||||
assertThrows<CannotUpdateException> { service.update(systemType) }
|
||||
assertThrows<CannotUpdateException> { logic.update(systemType) }
|
||||
}
|
||||
|
||||
// delete()
|
||||
|
@ -179,7 +179,7 @@ class MaterialTypeServiceTest :
|
|||
fun `delete() throws CannotDeleteException when deleting a system material type`() {
|
||||
whenever(repository.existsByIdAndSystemTypeIsTrue(systemType.id!!)).doReturn(true)
|
||||
|
||||
assertThrows<CannotDeleteException> { service.delete(systemType) }
|
||||
assertThrows<CannotDeleteException> { logic.delete(systemType) }
|
||||
}
|
||||
|
||||
override fun `delete() deletes in the repository`() {
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
|
@ -10,14 +10,14 @@ import kotlin.test.assertEquals
|
|||
import kotlin.test.assertTrue
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpdateDto, MixService, MixRepository>() {
|
||||
class MixLogicTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpdateDto, MixLogic, MixRepository>() {
|
||||
override val repository: MixRepository = mock()
|
||||
private val recipeService: RecipeService = mock()
|
||||
private val materialTypeService: MaterialTypeService = mock()
|
||||
private val mixMaterialService: MixMaterialService = mock()
|
||||
private val mixTypeService: MixTypeService = mock()
|
||||
override val service: MixService =
|
||||
spy(MixServiceImpl(repository, recipeService, materialTypeService, mixMaterialService, mixTypeService))
|
||||
private val recipeService: RecipeLogic = mock()
|
||||
private val materialTypeService: MaterialTypeLogic = mock()
|
||||
private val mixMaterialService: MixMaterialLogic = mock()
|
||||
private val mixTypeService: MixTypeLogic = mock()
|
||||
override val logic: MixLogic =
|
||||
spy(DefaultMixLogic(repository, recipeService, materialTypeService, mixMaterialService, mixTypeService))
|
||||
|
||||
override val entity: Mix = mix(id = 0L, location = "location")
|
||||
override val anotherEntity: Mix = mix(id = 1L)
|
||||
|
@ -39,7 +39,7 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
|
||||
whenever(repository.findAllByMixType(mixType)).doReturn(entityList)
|
||||
|
||||
val found = service.getAllByMixType(mixType)
|
||||
val found = logic.getAllByMixType(mixType)
|
||||
|
||||
assertEquals(entityList, found)
|
||||
}
|
||||
|
@ -70,12 +70,12 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
mixType.material.materialType!!
|
||||
)
|
||||
).doReturn(mixType)
|
||||
doReturn(true).whenever(service).existsById(mixWithId.id!!)
|
||||
doReturn(mixWithId).whenever(service).save(any<Mix>())
|
||||
doReturn(true).whenever(logic).existsById(mixWithId.id!!)
|
||||
doReturn(mixWithId).whenever(logic).save(any<Mix>())
|
||||
|
||||
val found = service.save(entitySaveDto)
|
||||
val found = logic.save(entitySaveDto)
|
||||
|
||||
verify(service).save(argThat<Mix> { this.recipe == mix.recipe })
|
||||
verify(logic).save(argThat<Mix> { this.recipe == mix.recipe })
|
||||
verify(recipeService).addMix(recipe, mixWithId)
|
||||
|
||||
// Verify if this method is called instead of the MixType's constructor, which does not check if the name is already taken by a material.
|
||||
|
@ -92,10 +92,10 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
op: MixUpdateDtoTestScope.() -> Unit
|
||||
) {
|
||||
with(scope) {
|
||||
doReturn(true).whenever(service).existsById(mix.id!!)
|
||||
doReturn(mix).whenever(service).getById(mix.id!!)
|
||||
doReturn(sharedMixType).whenever(service).mixTypeIsShared(mix.mixType)
|
||||
doAnswer { it.arguments[0] }.whenever(service).update(any<Mix>())
|
||||
doReturn(true).whenever(logic).existsById(mix.id!!)
|
||||
doReturn(mix).whenever(logic).getById(mix.id!!)
|
||||
doReturn(sharedMixType).whenever(logic).mixTypeIsShared(mix.mixType)
|
||||
doAnswer { it.arguments[0] }.whenever(logic).update(any<Mix>())
|
||||
|
||||
if (mixUpdateDto.materialTypeId != null) {
|
||||
whenever(materialTypeService.getById(materialType.id!!)).doReturn(materialType)
|
||||
|
@ -115,12 +115,12 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
override fun `update(dto) calls and returns update() with the created entity`() {
|
||||
val mixUpdateDto = spy(mixUpdateDto(id = 0L, name = null, materialTypeId = null))
|
||||
|
||||
doReturn(entity).whenever(service).getById(any())
|
||||
doReturn(entity).whenever(service).update(entity)
|
||||
doReturn(entity).whenever(logic).getById(any())
|
||||
doReturn(entity).whenever(logic).update(entity)
|
||||
|
||||
val found = service.update(mixUpdateDto)
|
||||
val found = logic.update(mixUpdateDto)
|
||||
|
||||
verify(service).update(entity)
|
||||
verify(logic).update(entity)
|
||||
|
||||
assertEquals(entity, found)
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
whenever(mixTypeService.saveForNameAndMaterialType(mixUpdateDto.name!!, materialType))
|
||||
.doReturn(newMixType)
|
||||
|
||||
val found = service.update(mixUpdateDto)
|
||||
val found = logic.update(mixUpdateDto)
|
||||
|
||||
verify(mixTypeService).saveForNameAndMaterialType(mixUpdateDto.name!!, materialType)
|
||||
|
||||
|
@ -145,7 +145,7 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
whenever(mixTypeService.updateForNameAndMaterialType(mixType, mixUpdateDto.name!!, materialType))
|
||||
.doReturn(newMixType)
|
||||
|
||||
val found = service.update(mixUpdateDto)
|
||||
val found = logic.update(mixUpdateDto)
|
||||
|
||||
verify(mixTypeService).updateForNameAndMaterialType(mixType, mixUpdateDto.name!!, materialType)
|
||||
|
||||
|
@ -174,7 +174,7 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
}.toSet()
|
||||
}
|
||||
|
||||
val found = service.update(mixUpdateDto)
|
||||
val found = logic.update(mixUpdateDto)
|
||||
|
||||
mixMaterials.forEach {
|
||||
assertTrue {
|
||||
|
@ -197,10 +197,10 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
mixLocationDto(mixId = 3, location = "Loc 3")
|
||||
)
|
||||
|
||||
service.updateLocations(locations)
|
||||
logic.updateLocations(locations)
|
||||
|
||||
locations.forEach {
|
||||
verify(service).updateLocation(it)
|
||||
verify(logic).updateLocation(it)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,7 +210,7 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
fun `updateLocation() updates the location of a mix in the repository according to the given MixLocationDto`() {
|
||||
val locationDto = mixLocationDto(mixId = 0L, location = "Location")
|
||||
|
||||
service.updateLocation(locationDto)
|
||||
logic.updateLocation(locationDto)
|
||||
|
||||
verify(repository).updateLocationById(locationDto.mixId, locationDto.location)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
|
@ -12,10 +12,10 @@ import kotlin.test.assertNotEquals
|
|||
import kotlin.test.assertTrue
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class MixMaterialServiceTest : AbstractModelServiceTest<MixMaterial, MixMaterialService, MixMaterialRepository>() {
|
||||
class MixMaterialLogicTest : AbstractModelServiceTest<MixMaterial, MixMaterialLogic, MixMaterialRepository>() {
|
||||
override val repository: MixMaterialRepository = mock()
|
||||
private val materialService: MaterialService = mock()
|
||||
override val service: MixMaterialService = spy(MixMaterialServiceImpl(repository, materialService))
|
||||
private val materialService: MaterialLogic = mock()
|
||||
override val logic: MixMaterialLogic = spy(DefaultMixMaterialLogic(repository, materialService))
|
||||
|
||||
private val material: Material = material(id = 0L)
|
||||
override val entity: MixMaterial = mixMaterial(id = 0L, material = material, quantity = 1000f)
|
||||
|
@ -27,7 +27,7 @@ class MixMaterialServiceTest : AbstractModelServiceTest<MixMaterial, MixMaterial
|
|||
fun `existsByMaterial() returns true when a mix material with the given material exists`() {
|
||||
whenever(repository.existsByMaterial(material)).doReturn(true)
|
||||
|
||||
val found = service.existsByMaterial(material)
|
||||
val found = logic.existsByMaterial(material)
|
||||
|
||||
assertTrue(found)
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class MixMaterialServiceTest : AbstractModelServiceTest<MixMaterial, MixMaterial
|
|||
fun `existsByMaterial() returns false when no mix material with the given material exists`() {
|
||||
whenever(repository.existsByMaterial(material)).doReturn(false)
|
||||
|
||||
val found = service.existsByMaterial(material)
|
||||
val found = logic.existsByMaterial(material)
|
||||
|
||||
assertFalse(found)
|
||||
}
|
||||
|
@ -60,12 +60,12 @@ class MixMaterialServiceTest : AbstractModelServiceTest<MixMaterial, MixMaterial
|
|||
position = this.position
|
||||
)
|
||||
}
|
||||
}.whenever(service).create(any<MixMaterialDto>())
|
||||
}.whenever(logic).create(any<MixMaterialDto>())
|
||||
|
||||
val found = service.create(mixMaterialDtos)
|
||||
val found = logic.create(mixMaterialDtos)
|
||||
|
||||
mixMaterialDtos.forEach { dto ->
|
||||
verify(service).create(dto)
|
||||
verify(logic).create(dto)
|
||||
assertTrue {
|
||||
found.any {
|
||||
it.material.id == dto.materialId && it.quantity == dto.quantity && it.position == dto.position
|
||||
|
@ -80,7 +80,7 @@ class MixMaterialServiceTest : AbstractModelServiceTest<MixMaterial, MixMaterial
|
|||
|
||||
whenever(materialService.getById(mixMaterialDto.materialId)).doAnswer { material(id = it.arguments[0] as Long) }
|
||||
|
||||
val found = service.create(mixMaterialDto)
|
||||
val found = logic.create(mixMaterialDto)
|
||||
|
||||
assertTrue {
|
||||
found.material.id == mixMaterialDto.materialId &&
|
||||
|
@ -96,9 +96,9 @@ class MixMaterialServiceTest : AbstractModelServiceTest<MixMaterial, MixMaterial
|
|||
val quantity = 5000f
|
||||
assertNotEquals(quantity, entity.quantity, message = "Quantities must not be equals for this test to works")
|
||||
|
||||
doAnswer { it.arguments[0] }.whenever(service).update(any())
|
||||
doAnswer { it.arguments[0] }.whenever(logic).update(any())
|
||||
|
||||
val found = service.updateQuantity(entity, quantity)
|
||||
val found = logic.updateQuantity(entity, quantity)
|
||||
|
||||
assertEquals(found.quantity, quantity)
|
||||
}
|
||||
|
@ -156,13 +156,13 @@ class MixMaterialServiceTest : AbstractModelServiceTest<MixMaterial, MixMaterial
|
|||
)
|
||||
|
||||
assertThrows<InvalidFirstMixMaterial> {
|
||||
service.validateMixMaterials(mixMaterials)
|
||||
logic.validateMixMaterials(mixMaterials)
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertInvalidMixMaterialsPositionsException(mixMaterials: Set<MixMaterial>, errorType: String) {
|
||||
val exception = assertThrows<InvalidMixMaterialsPositionsException> {
|
||||
service.validateMixMaterials(mixMaterials)
|
||||
logic.validateMixMaterials(mixMaterials)
|
||||
}
|
||||
|
||||
assertTrue { exception.errors.size == 1 }
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
||||
|
@ -13,11 +13,10 @@ import kotlin.test.assertEquals
|
|||
import kotlin.test.assertTrue
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService, MixTypeRepository>() {
|
||||
class MixTypeLogicTest : AbstractNamedModelServiceTest<MixType, MixTypeLogic, MixTypeRepository>() {
|
||||
override val repository: MixTypeRepository = mock()
|
||||
private val materialService: MaterialService = mock()
|
||||
private val mixService: MixService = mock()
|
||||
override val service: MixTypeService = spy(MixTypeServiceImpl(repository, materialService, mixService))
|
||||
private val materialService: MaterialLogic = mock()
|
||||
override val logic: MixTypeLogic = spy(DefaultMixTypeLogic(repository, materialService))
|
||||
|
||||
private val materialType: MaterialType = materialType()
|
||||
private val material: Material = material(id = 0L, materialType = materialType)
|
||||
|
@ -38,7 +37,7 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
|
|||
setOf(true, false).forEach {
|
||||
whenever(repository.existsByNameAndMaterialType(entity.name, materialType)).doReturn(it)
|
||||
|
||||
val found = service.existsByNameAndMaterialType(entity.name, materialType)
|
||||
val found = logic.existsByNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
assertTrue { found == it }
|
||||
}
|
||||
|
@ -50,7 +49,7 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
|
|||
fun `getByMaterial() returns the mix type with the given material`() {
|
||||
whenever(repository.findByMaterial(material)).doReturn(entity)
|
||||
|
||||
val found = service.getByMaterial(material)
|
||||
val found = logic.getByMaterial(material)
|
||||
|
||||
assertEquals(entity, found)
|
||||
}
|
||||
|
@ -59,7 +58,7 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
|
|||
fun `getByMaterial() throws NotFoundException when no mix type with the given material exists`() {
|
||||
whenever(repository.findByMaterial(material)).doReturn(null)
|
||||
|
||||
assertThrows<NotFoundException> { service.getByMaterial(material) }
|
||||
assertThrows<NotFoundException> { logic.getByMaterial(material) }
|
||||
.assertErrorCode("name")
|
||||
}
|
||||
|
||||
|
@ -69,7 +68,7 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
|
|||
fun `getByNameAndMaterialType() returns the mix type with the given name and material type`() {
|
||||
whenever(repository.findByNameAndMaterialType(entity.name, materialType)).doReturn(entity)
|
||||
|
||||
val found = service.getByNameAndMaterialType(entity.name, materialType)
|
||||
val found = logic.getByNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
assertEquals(entity, found)
|
||||
}
|
||||
|
@ -77,24 +76,24 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
|
|||
// getOrCreateForNameAndMaterialType()
|
||||
@Test
|
||||
fun `getOrCreateForNameAndMaterialType() calls getForNameAndMaterialType() when a mix type with the given name and material type exists`() {
|
||||
doReturn(true).whenever(service).existsByNameAndMaterialType(entity.name, materialType)
|
||||
doReturn(entity).whenever(service).getByNameAndMaterialType(entity.name, materialType)
|
||||
doReturn(true).whenever(logic).existsByNameAndMaterialType(entity.name, materialType)
|
||||
doReturn(entity).whenever(logic).getByNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
val found = service.getOrCreateForNameAndMaterialType(entity.name, materialType)
|
||||
val found = logic.getOrCreateForNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
verify(service).getByNameAndMaterialType(entity.name, materialType)
|
||||
verify(logic).getByNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
assertEquals(entity, found)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getOrCreateForNameAndMaterialType() calls saveForNameAndMaterialType() when no mix type with the given name and material type exists`() {
|
||||
doReturn(false).whenever(service).existsByNameAndMaterialType(entity.name, materialType)
|
||||
doReturn(entity).whenever(service).saveForNameAndMaterialType(entity.name, materialType)
|
||||
doReturn(false).whenever(logic).existsByNameAndMaterialType(entity.name, materialType)
|
||||
doReturn(entity).whenever(logic).saveForNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
val found = service.getOrCreateForNameAndMaterialType(entity.name, materialType)
|
||||
val found = logic.getOrCreateForNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
verify(service).saveForNameAndMaterialType(entity.name, materialType)
|
||||
verify(logic).saveForNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
assertEquals(entity, found)
|
||||
}
|
||||
|
@ -105,7 +104,7 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
|
|||
fun `save() throws AlreadyExistsException when a material with the name of the new mix type exists`() {
|
||||
whenever(materialService.existsByName(entity.name)).doReturn(true)
|
||||
|
||||
assertThrows<AlreadyExistsException> { service.save(entity) }
|
||||
assertThrows<AlreadyExistsException> { logic.save(entity) }
|
||||
.assertErrorCode("name")
|
||||
}
|
||||
|
||||
|
@ -116,11 +115,11 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
|
|||
val name = entity.name
|
||||
val materialType = materialType()
|
||||
|
||||
doAnswer { it.arguments[0] }.whenever(service).save(any())
|
||||
doAnswer { it.arguments[0] }.whenever(logic).save(any())
|
||||
|
||||
val found = service.saveForNameAndMaterialType(name, materialType)
|
||||
val found = logic.saveForNameAndMaterialType(name, materialType)
|
||||
|
||||
verify(service).save(any())
|
||||
verify(logic).save(any())
|
||||
|
||||
assertEquals(name, found.name)
|
||||
assertEquals(name, found.material.name)
|
||||
|
@ -136,11 +135,11 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
|
|||
val name = entity.name
|
||||
val materialType = materialType()
|
||||
|
||||
doAnswer { it.arguments[0] }.whenever(service).update(any())
|
||||
doAnswer { it.arguments[0] }.whenever(logic).update(any())
|
||||
|
||||
val found = service.updateForNameAndMaterialType(mixType, name, materialType)
|
||||
val found = logic.updateForNameAndMaterialType(mixType, name, materialType)
|
||||
|
||||
verify(service).update(any())
|
||||
verify(logic).update(any())
|
||||
|
||||
assertEquals(mixType.id, found.id)
|
||||
assertEquals(name, found.name)
|
|
@ -1,14 +1,14 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
||||
import dev.fyloz.colorrecipesexplorer.logic.config.ConfigurationLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.CachedFile
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.WriteableFileLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.users.GroupLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.model.account.group
|
||||
import dev.fyloz.colorrecipesexplorer.repository.RecipeRepository
|
||||
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.CachedFile
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.WriteableFileService
|
||||
import dev.fyloz.colorrecipesexplorer.service.users.GroupService
|
||||
import dev.fyloz.colorrecipesexplorer.utils.FilePath
|
||||
import io.mockk.*
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
|
@ -22,19 +22,19 @@ import java.time.Period
|
|||
import kotlin.test.*
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class RecipeServiceTest :
|
||||
AbstractExternalModelServiceTest<Recipe, RecipeSaveDto, RecipeUpdateDto, RecipeService, RecipeRepository>() {
|
||||
class RecipeLogicTest :
|
||||
AbstractExternalModelServiceTest<Recipe, RecipeSaveDto, RecipeUpdateDto, RecipeLogic, RecipeRepository>() {
|
||||
override val repository: RecipeRepository = mock()
|
||||
private val companyService: CompanyService = mock()
|
||||
private val mixService: MixService = mock()
|
||||
private val groupService: GroupService = mock()
|
||||
private val recipeStepService: RecipeStepService = mock()
|
||||
private val configService: ConfigurationService = mock()
|
||||
override val service: RecipeService =
|
||||
private val companyLogic: CompanyLogic = mock()
|
||||
private val mixService: MixLogic = mock()
|
||||
private val groupService: GroupLogic = mock()
|
||||
private val recipeStepService: RecipeStepLogic = mock()
|
||||
private val configService: ConfigurationLogic = mock()
|
||||
override val logic: RecipeLogic =
|
||||
spy(
|
||||
RecipeServiceImpl(
|
||||
DefaultRecipeLogic(
|
||||
repository,
|
||||
companyService,
|
||||
companyLogic,
|
||||
mixService,
|
||||
recipeStepService,
|
||||
groupService,
|
||||
|
@ -51,7 +51,7 @@ class RecipeServiceTest :
|
|||
|
||||
@AfterEach
|
||||
override fun afterEach() {
|
||||
reset(companyService, mixService)
|
||||
reset(companyLogic, mixService)
|
||||
super.afterEach()
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ class RecipeServiceTest :
|
|||
fun `existsByCompany() returns true when at least one recipe exists for the given company`() {
|
||||
whenever(repository.existsByCompany(company)).doReturn(true)
|
||||
|
||||
val found = service.existsByCompany(company)
|
||||
val found = logic.existsByCompany(company)
|
||||
|
||||
assertTrue(found)
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ class RecipeServiceTest :
|
|||
fun `existsByCompany() returns false when no recipe exists for the given company`() {
|
||||
whenever(repository.existsByCompany(company)).doReturn(false)
|
||||
|
||||
val found = service.existsByCompany(company)
|
||||
val found = logic.existsByCompany(company)
|
||||
|
||||
assertFalse(found)
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ class RecipeServiceTest :
|
|||
setOf(true, false).forEach {
|
||||
whenever(repository.existsByNameAndCompany(entity.name, company)).doReturn(it)
|
||||
|
||||
val exists = service.existsByNameAndCompany(entity.name, company)
|
||||
val exists = logic.existsByNameAndCompany(entity.name, company)
|
||||
|
||||
assertEquals(it, exists)
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ class RecipeServiceTest :
|
|||
|
||||
whenever(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(period.toString())
|
||||
|
||||
val approbationExpired = service.isApprobationExpired(recipe)
|
||||
val approbationExpired = logic.isApprobationExpired(recipe)
|
||||
|
||||
assertNotNull(approbationExpired)
|
||||
assertFalse(approbationExpired)
|
||||
|
@ -110,7 +110,7 @@ class RecipeServiceTest :
|
|||
|
||||
whenever(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(period.toString())
|
||||
|
||||
val approbationExpired = service.isApprobationExpired(recipe)
|
||||
val approbationExpired = logic.isApprobationExpired(recipe)
|
||||
|
||||
assertNotNull(approbationExpired)
|
||||
assertTrue(approbationExpired)
|
||||
|
@ -123,7 +123,7 @@ class RecipeServiceTest :
|
|||
|
||||
whenever(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(period.toString())
|
||||
|
||||
val approbationExpired = service.isApprobationExpired(recipe)
|
||||
val approbationExpired = logic.isApprobationExpired(recipe)
|
||||
|
||||
assertNull(approbationExpired)
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ class RecipeServiceTest :
|
|||
|
||||
whenever(repository.findAllByName(entity.name)).doReturn(recipes)
|
||||
|
||||
val found = service.getAllByName(entity.name)
|
||||
val found = logic.getAllByName(entity.name)
|
||||
|
||||
assertEquals(recipes, found)
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ class RecipeServiceTest :
|
|||
val companies = listOf(entity, anotherEntity)
|
||||
whenever(repository.findAllByCompany(company)).doReturn(companies)
|
||||
|
||||
val found = service.getAllByCompany(company)
|
||||
val found = logic.getAllByCompany(company)
|
||||
|
||||
assertEquals(companies, found)
|
||||
}
|
||||
|
@ -157,17 +157,17 @@ class RecipeServiceTest :
|
|||
|
||||
@Test
|
||||
override fun `save(dto) calls and returns save() with the created entity`() {
|
||||
whenever(companyService.getById(company.id!!)).doReturn(company)
|
||||
doReturn(false).whenever(service).existsByNameAndCompany(entity.name, company)
|
||||
withBaseSaveDtoTest(entity, entitySaveDto, service, { argThat { this.id == null && this.color == color } })
|
||||
whenever(companyLogic.getById(company.id!!)).doReturn(company)
|
||||
doReturn(false).whenever(logic).existsByNameAndCompany(entity.name, company)
|
||||
withBaseSaveDtoTest(entity, entitySaveDto, logic, { argThat { this.id == null && this.color == color } })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `save(dto) throw AlreadyExistsException when a recipe with the given name and company exists in the repository`() {
|
||||
whenever(companyService.getById(company.id!!)).doReturn(company)
|
||||
doReturn(true).whenever(service).existsByNameAndCompany(entity.name, company)
|
||||
whenever(companyLogic.getById(company.id!!)).doReturn(company)
|
||||
doReturn(true).whenever(logic).existsByNameAndCompany(entity.name, company)
|
||||
|
||||
with(assertThrows<AlreadyExistsException> { service.save(entitySaveDto) }) {
|
||||
with(assertThrows<AlreadyExistsException> { logic.save(entitySaveDto) }) {
|
||||
this.assertErrorCode("company-name")
|
||||
}
|
||||
}
|
||||
|
@ -176,19 +176,19 @@ class RecipeServiceTest :
|
|||
|
||||
@Test
|
||||
override fun `update(dto) calls and returns update() with the created entity`() {
|
||||
doReturn(false).whenever(service).existsByNameAndCompany(entity.name, company)
|
||||
withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() })
|
||||
doReturn(false).whenever(logic).existsByNameAndCompany(entity.name, company)
|
||||
withBaseUpdateDtoTest(entity, entityUpdateDto, logic, { any() })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `update(dto) throws AlreadyExistsException when a recipe exists for the given name and company`() {
|
||||
val name = "another recipe"
|
||||
|
||||
doReturn(entity).whenever(service).getById(entity.id!!)
|
||||
doReturn(true).whenever(service).existsByNameAndCompany(name, company)
|
||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||
doReturn(true).whenever(logic).existsByNameAndCompany(name, company)
|
||||
doReturn(name).whenever(entityUpdateDto).name
|
||||
|
||||
with(assertThrows<AlreadyExistsException> { service.update(entityUpdateDto) }) {
|
||||
with(assertThrows<AlreadyExistsException> { logic.update(entityUpdateDto) }) {
|
||||
this.assertErrorCode("company-name")
|
||||
}
|
||||
}
|
||||
|
@ -210,12 +210,12 @@ class RecipeServiceTest :
|
|||
)
|
||||
val publicData = recipePublicDataDto(recipeId = recipe.id!!, notes = notes)
|
||||
|
||||
doReturn(recipe).whenever(service).getById(recipe.id!!)
|
||||
doAnswer { it.arguments[0] }.whenever(service).update(any<Recipe>())
|
||||
doReturn(recipe).whenever(logic).getById(recipe.id!!)
|
||||
doAnswer { it.arguments[0] }.whenever(logic).update(any<Recipe>())
|
||||
|
||||
service.updatePublicData(publicData)
|
||||
logic.updatePublicData(publicData)
|
||||
|
||||
verify(service).update(argThat<Recipe> {
|
||||
verify(logic).update(argThat<Recipe> {
|
||||
assertTrue { this.groupsInformation.first { it.group.id == 1L }.note == notes.first { it.groupId == 1L }.content }
|
||||
assertTrue { this.groupsInformation.first { it.group.id == 2L }.note == notes.first { it.groupId == 2L }.content }
|
||||
assertTrue { this.groupsInformation.any { it.group.id == 3L } && this.groupsInformation.first { it.group.id == 3L }.note == null }
|
||||
|
@ -225,7 +225,7 @@ class RecipeServiceTest :
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `updatePublicData() update the location of a recipe mixes in the mix service according to the RecipePublicDataDto`() {
|
||||
fun `updatePublicData() update the location of a recipe mixes in the mix logic according to the RecipePublicDataDto`() {
|
||||
val publicData = recipePublicDataDto(
|
||||
mixesLocation = setOf(
|
||||
mixLocationDto(mixId = 0L, location = "Loc 1"),
|
||||
|
@ -233,10 +233,10 @@ class RecipeServiceTest :
|
|||
)
|
||||
)
|
||||
|
||||
service.updatePublicData(publicData)
|
||||
logic.updatePublicData(publicData)
|
||||
|
||||
verify(mixService).updateLocations(publicData.mixesLocation!!)
|
||||
verify(service, times(0)).update(any<Recipe>())
|
||||
verify(logic, times(0)).update(any<Recipe>())
|
||||
}
|
||||
|
||||
// addMix()
|
||||
|
@ -246,11 +246,11 @@ class RecipeServiceTest :
|
|||
val mix = mix(id = 0L)
|
||||
val recipe = recipe(id = 0L, mixes = mutableListOf())
|
||||
|
||||
doAnswer { it.arguments[0] }.whenever(service).update(any<Recipe>())
|
||||
doAnswer { it.arguments[0] }.whenever(logic).update(any<Recipe>())
|
||||
|
||||
val found = service.addMix(recipe, mix)
|
||||
val found = logic.addMix(recipe, mix)
|
||||
|
||||
verify(service).update(any<Recipe>())
|
||||
verify(logic).update(any<Recipe>())
|
||||
|
||||
assertEquals(recipe.id, found.id)
|
||||
assertTrue(found.mixes.contains(mix))
|
||||
|
@ -264,11 +264,11 @@ class RecipeServiceTest :
|
|||
val mix = mix(id = 0L, recipe = recipe)
|
||||
recipe.mixes.add(mix)
|
||||
|
||||
doAnswer { it.arguments[0] }.whenever(service).update(any<Recipe>())
|
||||
doAnswer { it.arguments[0] }.whenever(logic).update(any<Recipe>())
|
||||
|
||||
val found = service.removeMix(mix)
|
||||
val found = logic.removeMix(mix)
|
||||
|
||||
verify(service).update(any<Recipe>())
|
||||
verify(logic).update(any<Recipe>())
|
||||
|
||||
assertEquals(recipe.id, found.id)
|
||||
assertFalse(found.mixes.contains(mix))
|
||||
|
@ -276,11 +276,11 @@ class RecipeServiceTest :
|
|||
}
|
||||
|
||||
private class RecipeImageServiceTestContext {
|
||||
val fileService = mockk<WriteableFileService> {
|
||||
val fileService = mockk<WriteableFileLogic> {
|
||||
every { write(any<MultipartFile>(), any(), any()) } just Runs
|
||||
every { delete(any()) } just Runs
|
||||
}
|
||||
val recipeImageService = spyk(RecipeImageServiceImpl(fileService))
|
||||
val recipeImageService = spyk(DefaultRecipeImageLogic(fileService))
|
||||
val recipe = spyk(recipe())
|
||||
val recipeImagesIds = setOf(1L, 10L, 21L)
|
||||
val recipeImagesNames = recipeImagesIds.map { it.imageName }.toSet()
|
||||
|
@ -293,7 +293,7 @@ private class RecipeImageServiceTestContext {
|
|||
get() = "${recipe.imagesDirectoryPath}/$this$RECIPE_IMAGE_EXTENSION"
|
||||
}
|
||||
|
||||
class RecipeImageServiceTest {
|
||||
class RecipeImageLogicTest {
|
||||
@AfterEach
|
||||
internal fun afterEach() {
|
||||
clearAllMocks()
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import dev.fyloz.colorrecipesexplorer.model.RecipeGroupInformation
|
||||
|
@ -13,10 +13,10 @@ import org.junit.jupiter.api.assertThrows
|
|||
import kotlin.test.assertTrue
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class RecipeStepServiceTest :
|
||||
AbstractModelServiceTest<RecipeStep, RecipeStepService, RecipeStepRepository>() {
|
||||
class RecipeStepLogicTest :
|
||||
AbstractModelServiceTest<RecipeStep, RecipeStepLogic, RecipeStepRepository>() {
|
||||
override val repository: RecipeStepRepository = mock()
|
||||
override val service: RecipeStepService = spy(RecipeStepServiceImpl(repository))
|
||||
override val logic: RecipeStepLogic = spy(DefaultRecipeStepLogic(repository))
|
||||
|
||||
override val entity: RecipeStep = recipeStep(id = 0L, message = "message")
|
||||
override val anotherEntity: RecipeStep = recipeStep(id = 1L, message = "another message")
|
||||
|
@ -26,19 +26,19 @@ class RecipeStepServiceTest :
|
|||
@Test
|
||||
fun `validateGroupInformationSteps() calls validateSteps() with the given RecipeGroupInformation steps`() {
|
||||
withGroupInformation {
|
||||
service.validateGroupInformationSteps(this)
|
||||
logic.validateGroupInformationSteps(this)
|
||||
|
||||
verify(service).validateSteps(this.steps!!)
|
||||
verify(logic).validateSteps(this.steps!!)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `validateGroupInformationSteps() throws InvalidGroupStepsPositionsException when validateSteps() throws an InvalidStepsPositionsException`() {
|
||||
withGroupInformation {
|
||||
doAnswer { throw InvalidStepsPositionsException(setOf()) }.whenever(service).validateSteps(this.steps!!)
|
||||
doAnswer { throw InvalidStepsPositionsException(setOf()) }.whenever(logic).validateSteps(this.steps!!)
|
||||
|
||||
assertThrows<InvalidGroupStepsPositionsException> {
|
||||
service.validateGroupInformationSteps(this)
|
||||
logic.validateGroupInformationSteps(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ class RecipeStepServiceTest :
|
|||
|
||||
private fun assertInvalidStepsPositionsException(steps: MutableSet<RecipeStep>, errorType: String) {
|
||||
val exception = assertThrows<InvalidStepsPositionsException> {
|
||||
service.validateSteps(steps)
|
||||
logic.validateSteps(steps)
|
||||
}
|
||||
|
||||
assertTrue { exception.errors.size == 1 }
|
|
@ -1,10 +1,10 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
package dev.fyloz.colorrecipesexplorer.logic
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.logic.config.ConfigurationLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.files.WriteableFileLogic
|
||||
import dev.fyloz.colorrecipesexplorer.model.ConfigurationType
|
||||
import dev.fyloz.colorrecipesexplorer.model.configuration
|
||||
import dev.fyloz.colorrecipesexplorer.repository.TouchUpKitRepository
|
||||
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.WriteableFileService
|
||||
import dev.fyloz.colorrecipesexplorer.utils.PdfDocument
|
||||
import dev.fyloz.colorrecipesexplorer.utils.toByteArrayResource
|
||||
import io.mockk.*
|
||||
|
@ -15,11 +15,11 @@ import kotlin.test.assertEquals
|
|||
|
||||
private class TouchUpKitServiceTestContext {
|
||||
val touchUpKitRepository = mockk<TouchUpKitRepository>()
|
||||
val fileService = mockk<WriteableFileService> {
|
||||
val fileService = mockk<WriteableFileLogic> {
|
||||
every { write(any<ByteArrayResource>(), any(), any()) } just Runs
|
||||
}
|
||||
val configService = mockk<ConfigurationService>(relaxed = true)
|
||||
val touchUpKitService = spyk(TouchUpKitServiceImpl(fileService, configService, touchUpKitRepository))
|
||||
val configService = mockk<ConfigurationLogic>(relaxed = true)
|
||||
val touchUpKitService = spyk(DefaultTouchUpKitLogic(fileService, configService, touchUpKitRepository))
|
||||
val pdfDocumentData = mockk<ByteArrayResource>()
|
||||
val pdfDocument = mockk<PdfDocument> {
|
||||
mockkStatic(PdfDocument::toByteArrayResource)
|
||||
|
@ -28,7 +28,7 @@ private class TouchUpKitServiceTestContext {
|
|||
}
|
||||
}
|
||||
|
||||
class TouchUpKitServiceTest {
|
||||
class TouchUpKitLogicTest {
|
||||
private val job = "job"
|
||||
|
||||
@AfterEach
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.files
|
||||
package dev.fyloz.colorrecipesexplorer.logic.files
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.utils.FilePath
|
||||
import dev.fyloz.memorycache.MemoryCache
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.files
|
||||
package dev.fyloz.colorrecipesexplorer.logic.files
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties
|
||||
import dev.fyloz.colorrecipesexplorer.utils.File
|
||||
|
@ -21,11 +21,11 @@ private const val mockFilePath = "existingFile"
|
|||
private val mockFilePathPath = Path.of(mockFilePath)
|
||||
private val mockFileData = byteArrayOf(0x1, 0x8, 0xa, 0xf)
|
||||
|
||||
class FileServiceTest {
|
||||
class FileLogicTest {
|
||||
private val fileCacheMock = mockk<FileCache> {
|
||||
every { setExists(any(), any()) } just runs
|
||||
}
|
||||
private val fileService = spyk(FileServiceImpl(fileCacheMock, creProperties))
|
||||
private val fileService = spyk(DefaultFileLogic(fileCacheMock, creProperties))
|
||||
|
||||
private val mockFile = mockk<File> {
|
||||
every { file } returns mockk()
|
|
@ -1,4 +1,4 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service.files
|
||||
package dev.fyloz.colorrecipesexplorer.logic.files
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.utils.FilePath
|
||||
import io.mockk.clearAllMocks
|
||||
|
@ -14,10 +14,10 @@ import kotlin.test.assertEquals
|
|||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ResourceFileServiceTest {
|
||||
class ResourceFileLogicTest {
|
||||
private val resourceLoader = mockk<ResourceLoader>()
|
||||
|
||||
private val service = spyk(ResourceFileService(resourceLoader))
|
||||
private val logic = spyk(ResourceFileLogic(resourceLoader))
|
||||
|
||||
@AfterEach
|
||||
fun afterEach() {
|
||||
|
@ -26,7 +26,7 @@ class ResourceFileServiceTest {
|
|||
|
||||
private fun existsTest(shouldExists: Boolean, test: (String) -> Unit) {
|
||||
val path = "unit_test_resource"
|
||||
with(service) {
|
||||
with(logic) {
|
||||
every { fullPath(path) } returns mockk {
|
||||
every { resource } returns mockk {
|
||||
every { exists() } returns shouldExists
|
||||
|
@ -40,7 +40,7 @@ class ResourceFileServiceTest {
|
|||
@Test
|
||||
fun `exists() returns true when a resource exists at the given path`() {
|
||||
existsTest(true) { path ->
|
||||
val found = service.exists(path)
|
||||
val found = logic.exists(path)
|
||||
|
||||
assertTrue { found }
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ class ResourceFileServiceTest {
|
|||
@Test
|
||||
fun `exists() returns false when no resource exists at the given path`() {
|
||||
existsTest(false) { path ->
|
||||
val found = service.exists(path)
|
||||
val found = logic.exists(path)
|
||||
|
||||
assertFalse { found }
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ class ResourceFileServiceTest {
|
|||
every { exists() } returns shouldExists
|
||||
}
|
||||
val path = "unit_test_path"
|
||||
with(service) {
|
||||
with(logic) {
|
||||
every { fullPath(path) } returns mockk {
|
||||
every { resource } returns mockResource
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ class ResourceFileServiceTest {
|
|||
@Test
|
||||
fun `read() returns the resource at the given path`() {
|
||||
readTest(true) { resource, path ->
|
||||
val found = service.read(path)
|
||||
val found = logic.read(path)
|
||||
|
||||
assertEquals(resource, found)
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ class ResourceFileServiceTest {
|
|||
fun `read() throws FileNotFoundException when no resource exists at the given path`() {
|
||||
readTest(false) { _, path ->
|
||||
assertThrows<FileNotFoundException> {
|
||||
service.read(path)
|
||||
logic.read(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ class ResourceFileServiceTest {
|
|||
val path = "unit_test_path"
|
||||
val expectedPath = "classpath:$path"
|
||||
|
||||
val found = service.fullPath(path)
|
||||
val found = logic.fullPath(path)
|
||||
|
||||
assertEquals(expectedPath, found.value)
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ class ResourceFileServiceTest {
|
|||
|
||||
every { resourceLoader.getResource(filePath.value) } returns resource
|
||||
|
||||
with(service) {
|
||||
with(logic) {
|
||||
val found = filePath.resource
|
||||
|
||||
assertEquals(resource, found)
|
Loading…
Reference in New Issue