feature/#25-dtos #28

Merged
william merged 11 commits from feature/#25-dtos into develop 2022-04-20 22:42:41 -04:00
56 changed files with 756 additions and 762 deletions
Showing only changes of commit d839543704 - Show all commits

View File

@ -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;
}
/**

View File

@ -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)

View File

@ -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 }
}
}

View 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)
}

View File

@ -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))
}
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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)
}

View File

@ -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 } }

View File

@ -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)

View File

@ -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)
}
}

View File

@ -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
)

View File

@ -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)
}

View File

@ -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 }

View File

@ -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)

View File

@ -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

View File

@ -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()
}

View File

@ -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()

View File

@ -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")

View File

@ -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

View 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 {

View File

@ -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()

View File

@ -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")
}

View File

@ -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"

View File

@ -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()
}

View File

@ -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 {

View File

@ -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
)

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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()
}

View File

@ -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))
}

View File

@ -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))
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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())

View File

@ -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")
}
}

View File

@ -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)

View File

@ -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()

View File

@ -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()
})
}

View File

@ -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)
}

View File

@ -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()

View File

@ -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)

View File

@ -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`() {

View File

@ -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)
}

View File

@ -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 }

View File

@ -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)

View File

@ -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()

View File

@ -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 }

View File

@ -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

View File

@ -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

View 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.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()

View File

@ -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)