#25 Rename service to logic
continuous-integration/drone/push Build is passing Details

This commit is contained in:
FyloZ 2022-02-13 22:05:05 -05:00
parent 5409bc8861
commit d839543704
Signed by: william
GPG Key ID: 835378AE9AF4AE97
56 changed files with 756 additions and 762 deletions

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.model.Recipe;
import dev.fyloz.colorrecipesexplorer.service.RecipeService;
import dev.fyloz.colorrecipesexplorer.xlsx.XlsxExporter; import dev.fyloz.colorrecipesexplorer.xlsx.XlsxExporter;
import mu.KotlinLogging;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
@ -17,14 +18,12 @@ import java.util.zip.ZipOutputStream;
@Service @Service
@Profile("!emergency") @Profile("!emergency")
public class XlsService { public class XlsService {
private final RecipeLogic recipeService;
private final RecipeService recipeService; private final Logger logger = KotlinLogging.INSTANCE.logger("XlsService");
private final Logger logger;
@Autowired @Autowired
public XlsService(RecipeService recipeService, Logger logger) { public XlsService(RecipeLogic recipeLogic) {
this.recipeService = recipeService; this.recipeService = recipeLogic;
this.logger = logger;
} }
/** /**

View File

@ -3,9 +3,9 @@ package dev.fyloz.colorrecipesexplorer
import dev.fyloz.colorrecipesexplorer.databasemanager.CreDatabase import dev.fyloz.colorrecipesexplorer.databasemanager.CreDatabase
import dev.fyloz.colorrecipesexplorer.databasemanager.databaseContext import dev.fyloz.colorrecipesexplorer.databasemanager.databaseContext
import dev.fyloz.colorrecipesexplorer.databasemanager.databaseUpdaterProperties 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.model.ConfigurationType
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService import mu.KotlinLogging
import org.slf4j.Logger import org.slf4j.Logger
import org.springframework.boot.jdbc.DataSourceBuilder import org.springframework.boot.jdbc.DataSourceBuilder
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
@ -23,11 +23,12 @@ val DATABASE_NAME_REGEX = Regex("(\\w+)$")
@SpringConfiguration @SpringConfiguration
@DependsOn("configurationsInitializer", "configurationService") @DependsOn("configurationsInitializer", "configurationService")
class DataSourceConfiguration { class DataSourceConfiguration {
private val logger = KotlinLogging.logger {}
@Bean(name = ["dataSource"]) @Bean(name = ["dataSource"])
fun customDataSource( fun customDataSource(
logger: Logger,
environment: ConfigurableEnvironment, environment: ConfigurableEnvironment,
configurationService: ConfigurationService configurationService: ConfigurationLogic
): DataSource { ): DataSource {
fun getConfiguration(type: ConfigurationType) = fun getConfiguration(type: ConfigurationType) =
if (type.secure) configurationService.getSecure(type) 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.initializers.AbstractInitializer
import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties
import dev.fyloz.colorrecipesexplorer.emergencyMode import dev.fyloz.colorrecipesexplorer.emergencyMode
import dev.fyloz.colorrecipesexplorer.logic.config.ConfigurationLogic
import dev.fyloz.colorrecipesexplorer.rest.CRE_PROPERTIES import dev.fyloz.colorrecipesexplorer.rest.CRE_PROPERTIES
import dev.fyloz.colorrecipesexplorer.restartApplication import dev.fyloz.colorrecipesexplorer.restartApplication
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService import mu.KotlinLogging
import org.slf4j.Logger
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent
import org.springframework.context.ApplicationListener import org.springframework.context.ApplicationListener
import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Configuration
@ -20,10 +20,11 @@ import kotlin.concurrent.thread
@Order(Ordered.HIGHEST_PRECEDENCE) @Order(Ordered.HIGHEST_PRECEDENCE)
@RequireDatabase @RequireDatabase
class ApplicationReadyListener( class ApplicationReadyListener(
private val configurationService: ConfigurationService, private val configurationLogic: ConfigurationLogic,
private val creProperties: CreProperties, private val creProperties: CreProperties
private val logger: Logger
) : AbstractInitializer() { ) : AbstractInitializer() {
private val logger = KotlinLogging.logger {}
override fun initialize() { override fun initialize() {
if (emergencyMode) { if (emergencyMode) {
logger.error("Emergency mode is enabled, default material types will not be created") logger.error("Emergency mode is enabled, default material types will not be created")
@ -40,17 +41,17 @@ class ApplicationReadyListener(
} }
private fun initDatabaseConfigurations() { private fun initDatabaseConfigurations() {
configurationService.initializeProperties { !it.file } configurationLogic.initializeProperties { !it.file }
} }
} }
@Configuration("configurationsInitializer") @Configuration("configurationsInitializer")
class ConfigurationsInitializer( class ConfigurationsInitializer(
private val configurationService: ConfigurationService private val configurationLogic: ConfigurationLogic
) { ) {
@PostConstruct @PostConstruct
fun initializeFileConfigurations() { 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.CreProperties
import dev.fyloz.colorrecipesexplorer.config.properties.MaterialTypeProperties 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.ExpiringMemoryCache
import dev.fyloz.memorycache.MemoryCache import dev.fyloz.memorycache.MemoryCache
import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.boot.context.properties.EnableConfigurationProperties
@ -13,6 +13,6 @@ import org.springframework.context.annotation.Configuration
@EnableConfigurationProperties(MaterialTypeProperties::class, CreProperties::class) @EnableConfigurationProperties(MaterialTypeProperties::class, CreProperties::class)
class CreConfiguration(private val creProperties: CreProperties) { class CreConfiguration(private val creProperties: CreProperties) {
@Bean @Bean
fun fileCache(): MemoryCache<String, CachedFileSystemItem> = fun fileMemoryCache(): MemoryCache<String, CachedFileSystemItem> =
ExpiringMemoryCache(maxAccessCount = creProperties.fileCacheMaxAccessCount) 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.annotations.RequireDatabase
import dev.fyloz.colorrecipesexplorer.config.properties.MaterialTypeProperties 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.model.materialType
import dev.fyloz.colorrecipesexplorer.service.MaterialTypeService
import mu.KotlinLogging import mu.KotlinLogging
import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Configuration
@Configuration @Configuration
@RequireDatabase @RequireDatabase
class MaterialTypeInitializer( class MaterialTypeInitializer(
private val materialTypeService: MaterialTypeService, private val materialTypeLogic: MaterialTypeLogic,
private val materialTypeProperties: MaterialTypeProperties private val materialTypeProperties: MaterialTypeProperties
) : AbstractInitializer() { ) : AbstractInitializer() {
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
@ -24,21 +23,21 @@ class MaterialTypeInitializer(
private fun ensureSystemMaterialTypesExists() { private fun ensureSystemMaterialTypesExists() {
val systemTypes = materialTypeProperties.systemTypes.map { it.toMaterialType() } val systemTypes = materialTypeProperties.systemTypes.map { it.toMaterialType() }
val oldSystemTypes = materialTypeService.getAllSystemTypes().toMutableSet() val oldSystemTypes = materialTypeLogic.getAllSystemTypes().toMutableSet()
fun saveOrUpdateSystemType(type: MaterialType) { fun saveOrUpdateSystemType(type: MaterialType) {
if (materialTypeService.existsByName(type.name)) { if (materialTypeLogic.existsByName(type.name)) {
with(materialTypeService.getByName(type.name)) { with(materialTypeLogic.getByName(type.name)) {
if (!this.systemType) { if (!this.systemType) {
logger.info("Material type '${type.name}' already exists and will be flagged as a system type") 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 { } else {
logger.debug("System material type '${type.name}' already exists") logger.debug("System material type '${type.name}' already exists")
} }
} }
} else { } else {
logger.info("System material type '${type.name}' will be created") 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 // Remove old system types
oldSystemTypes.forEach { oldSystemTypes.forEach {
logger.info("Material type '${it.name}' is not a system type anymore") 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 package dev.fyloz.colorrecipesexplorer.config.initializers
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
import dev.fyloz.colorrecipesexplorer.logic.MixLogic
import dev.fyloz.colorrecipesexplorer.model.Mix import dev.fyloz.colorrecipesexplorer.model.Mix
import dev.fyloz.colorrecipesexplorer.model.MixMaterial import dev.fyloz.colorrecipesexplorer.model.MixMaterial
import dev.fyloz.colorrecipesexplorer.service.MixService
import dev.fyloz.colorrecipesexplorer.utils.merge import dev.fyloz.colorrecipesexplorer.utils.merge
import mu.KotlinLogging import mu.KotlinLogging
import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Configuration
@ -12,7 +12,7 @@ import java.util.*
@Configuration @Configuration
@RequireDatabase @RequireDatabase
class MixInitializer( class MixInitializer(
private val mixService: MixService private val mixLogic: MixLogic
) : AbstractInitializer() { ) : AbstractInitializer() {
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
@ -24,7 +24,7 @@ class MixInitializer(
private fun fixAllPositions() { private fun fixAllPositions() {
logger.debug("Validating mix materials positions...") logger.debug("Validating mix materials positions...")
mixService.getAll() mixLogic.getAll()
.filter { mix -> mix.mixMaterials.any { it.position == 0 } } .filter { mix -> mix.mixMaterials.any { it.position == 0 } }
.forEach(this::fixMixPositions) .forEach(this::fixMixPositions)
@ -48,7 +48,7 @@ class MixInitializer(
val updatedMixMaterials = mix.mixMaterials.merge(fixedMixMaterials) val updatedMixMaterials = mix.mixMaterials.merge(fixedMixMaterials)
with(mix.copy(mixMaterials = updatedMixMaterials.toMutableSet())) { with(mix.copy(mixMaterials = updatedMixMaterials.toMutableSet())) {
mixService.update(this) mixLogic.update(this)
} }
} }

View File

@ -1,10 +1,10 @@
package dev.fyloz.colorrecipesexplorer.config.initializers package dev.fyloz.colorrecipesexplorer.config.initializers
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
import dev.fyloz.colorrecipesexplorer.logic.RecipeLogic
import dev.fyloz.colorrecipesexplorer.model.Recipe import dev.fyloz.colorrecipesexplorer.model.Recipe
import dev.fyloz.colorrecipesexplorer.model.RecipeGroupInformation import dev.fyloz.colorrecipesexplorer.model.RecipeGroupInformation
import dev.fyloz.colorrecipesexplorer.model.RecipeStep import dev.fyloz.colorrecipesexplorer.model.RecipeStep
import dev.fyloz.colorrecipesexplorer.service.RecipeService
import dev.fyloz.colorrecipesexplorer.utils.merge import dev.fyloz.colorrecipesexplorer.utils.merge
import mu.KotlinLogging import mu.KotlinLogging
import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Configuration
@ -12,7 +12,7 @@ import org.springframework.context.annotation.Configuration
@Configuration @Configuration
@RequireDatabase @RequireDatabase
class RecipeInitializer( class RecipeInitializer(
private val recipeService: RecipeService private val recipeLogic: RecipeLogic
) : AbstractInitializer() { ) : AbstractInitializer() {
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
@ -24,7 +24,7 @@ class RecipeInitializer(
private fun fixAllPositions() { private fun fixAllPositions() {
logger.debug("Validating recipes steps positions...") logger.debug("Validating recipes steps positions...")
recipeService.getAll() recipeLogic.getAll()
.forEach(this::fixRecipePositions) .forEach(this::fixRecipePositions)
logger.debug("Recipes steps positions are valid!") logger.debug("Recipes steps positions are valid!")
@ -39,7 +39,7 @@ class RecipeInitializer(
val updatedGroupInformation = recipe.groupsInformation.merge(fixedGroupInformation) val updatedGroupInformation = recipe.groupsInformation.merge(fixedGroupInformation)
with(recipe.copy(groupsInformation = updatedGroupInformation.toMutableSet())) { 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 com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties
import dev.fyloz.colorrecipesexplorer.exception.NotFoundException 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.UserDetails
import dev.fyloz.colorrecipesexplorer.model.account.UserLoginRequest import dev.fyloz.colorrecipesexplorer.model.account.UserLoginRequest
import dev.fyloz.colorrecipesexplorer.model.account.UserOutputDto import dev.fyloz.colorrecipesexplorer.model.account.UserOutputDto
import dev.fyloz.colorrecipesexplorer.model.account.toAuthorities 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 dev.fyloz.colorrecipesexplorer.utils.addCookie
import io.jsonwebtoken.ExpiredJwtException import io.jsonwebtoken.ExpiredJwtException
import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.authentication.AuthenticationManager
@ -28,7 +28,7 @@ val blacklistedJwtTokens = mutableListOf<String>() // Not working, move to a ca
class JwtAuthenticationFilter( class JwtAuthenticationFilter(
private val authManager: AuthenticationManager, private val authManager: AuthenticationManager,
private val jwtService: JwtService, private val jwtLogic: JwtLogic,
private val securityProperties: CreSecurityProperties, private val securityProperties: CreSecurityProperties,
private val updateUserLoginTime: (Long) -> Unit private val updateUserLoginTime: (Long) -> Unit
) : UsernamePasswordAuthenticationFilter() { ) : UsernamePasswordAuthenticationFilter() {
@ -52,7 +52,7 @@ class JwtAuthenticationFilter(
auth: Authentication auth: Authentication
) { ) {
val userDetails = auth.principal as UserDetails val userDetails = auth.principal as UserDetails
val token = jwtService.buildJwt(userDetails) val token = jwtLogic.buildJwt(userDetails)
with(userDetails.user) { with(userDetails.user) {
logger.info("User ${this.id} (${this.firstName} ${this.lastName}) has logged in successfully") logger.info("User ${this.id} (${this.firstName} ${this.lastName}) has logged in successfully")
@ -72,9 +72,9 @@ class JwtAuthenticationFilter(
} }
class JwtAuthorizationFilter( class JwtAuthorizationFilter(
private val jwtService: JwtService, private val jwtLogic: JwtLogic,
authenticationManager: AuthenticationManager, authenticationManager: AuthenticationManager,
private val userDetailsService: UserDetailsService private val userDetailsLogic: UserDetailsLogic
) : BasicAuthenticationFilter(authenticationManager) { ) : BasicAuthenticationFilter(authenticationManager) {
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) { override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) {
fun tryLoginFromBearer(): Boolean { fun tryLoginFromBearer(): Boolean {
@ -109,7 +109,7 @@ class JwtAuthorizationFilter(
private fun getAuthentication(token: String): UsernamePasswordAuthenticationToken? { private fun getAuthentication(token: String): UsernamePasswordAuthenticationToken? {
return try { return try {
val user = jwtService.parseJwt(token.replace("Bearer", "")) val user = jwtLogic.parseJwt(token.replace("Bearer", ""))
getAuthenticationToken(user) getAuthenticationToken(user)
} catch (_: ExpiredJwtException) { } catch (_: ExpiredJwtException) {
null null
@ -120,7 +120,7 @@ class JwtAuthorizationFilter(
UsernamePasswordAuthenticationToken(user.id, null, user.permissions.toAuthorities()) UsernamePasswordAuthenticationToken(user.id, null, user.permissions.toAuthorities())
private fun getAuthenticationToken(userId: Long): UsernamePasswordAuthenticationToken? = try { private fun getAuthenticationToken(userId: Long): UsernamePasswordAuthenticationToken? = try {
val userDetails = userDetailsService.loadUserById(userId) val userDetails = userDetailsLogic.loadUserById(userId)
UsernamePasswordAuthenticationToken(userDetails.username, null, userDetails.authorities) UsernamePasswordAuthenticationToken(userDetails.username, null, userDetails.authorities)
} catch (_: NotFoundException) { } catch (_: NotFoundException) {
null null

View File

@ -2,12 +2,11 @@ package dev.fyloz.colorrecipesexplorer.config.security
import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties
import dev.fyloz.colorrecipesexplorer.emergencyMode 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.Permission
import dev.fyloz.colorrecipesexplorer.model.account.User 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 mu.KotlinLogging
import org.slf4j.Logger import org.slf4j.Logger
import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.boot.context.properties.EnableConfigurationProperties
@ -38,8 +37,8 @@ private const val rootUserFirstName = "Root"
private const val rootUserLastName = "User" private const val rootUserLastName = "User"
abstract class BaseSecurityConfig( abstract class BaseSecurityConfig(
private val userDetailsService: UserDetailsService, private val userDetailsLogic: UserDetailsLogic,
private val jwtService: JwtService, private val jwtLogic: JwtLogic,
private val environment: Environment, private val environment: Environment,
protected val securityProperties: CreSecurityProperties protected val securityProperties: CreSecurityProperties
) : WebSecurityConfigurerAdapter() { ) : WebSecurityConfigurerAdapter() {
@ -70,7 +69,7 @@ abstract class BaseSecurityConfig(
} }
override fun configure(authBuilder: AuthenticationManagerBuilder) { override fun configure(authBuilder: AuthenticationManagerBuilder) {
authBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder) authBuilder.userDetailsService(userDetailsLogic).passwordEncoder(passwordEncoder)
} }
override fun configure(http: HttpSecurity) { override fun configure(http: HttpSecurity) {
@ -81,13 +80,13 @@ abstract class BaseSecurityConfig(
.addFilter( .addFilter(
JwtAuthenticationFilter( JwtAuthenticationFilter(
authenticationManager(), authenticationManager(),
jwtService, jwtLogic,
securityProperties, securityProperties,
this::updateUserLoginTime this::updateUserLoginTime
) )
) )
.addFilter( .addFilter(
JwtAuthorizationFilter(jwtService, authenticationManager(), userDetailsService) JwtAuthorizationFilter(jwtLogic, authenticationManager(), userDetailsLogic)
) )
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and() .and()
@ -118,12 +117,12 @@ abstract class BaseSecurityConfig(
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableConfigurationProperties(CreSecurityProperties::class) @EnableConfigurationProperties(CreSecurityProperties::class)
class SecurityConfig( class SecurityConfig(
@Lazy userDetailsService: UserDetailsService, @Lazy userDetailsLogic: UserDetailsLogic,
@Lazy private val userService: UserService, @Lazy private val userLogic: UserLogic,
jwtService: JwtService, jwtLogic: JwtLogic,
environment: Environment, environment: Environment,
securityProperties: CreSecurityProperties securityProperties: CreSecurityProperties
) : BaseSecurityConfig(userDetailsService, jwtService, environment, securityProperties) { ) : BaseSecurityConfig(userDetailsLogic, jwtLogic, environment, securityProperties) {
override val logger = KotlinLogging.logger {} override val logger = KotlinLogging.logger {}
@PostConstruct @PostConstruct
@ -137,7 +136,7 @@ class SecurityConfig(
} }
override fun updateUserLoginTime(userId: Long) { override fun updateUserLoginTime(userId: Long) {
userService.updateLastLoginTime(userId) userLogic.updateLastLoginTime(userId)
} }
private fun createRootUser() { private fun createRootUser() {
@ -146,8 +145,8 @@ class SecurityConfig(
} }
with(securityProperties.root!!) { with(securityProperties.root!!) {
if (!userService.existsById(this.id)) { if (!userLogic.existsById(this.id)) {
userService.save( userLogic.save(
User( User(
id = this.id, id = this.id,
firstName = rootUserFirstName, firstName = rootUserFirstName,
@ -166,11 +165,11 @@ class SecurityConfig(
@Profile("emergency") @Profile("emergency")
@EnableConfigurationProperties(CreSecurityProperties::class) @EnableConfigurationProperties(CreSecurityProperties::class)
class EmergencySecurityConfig( class EmergencySecurityConfig(
userDetailsService: UserDetailsService, userDetailsLogic: UserDetailsLogic,
jwtService: JwtService, jwtLogic: JwtLogic,
environment: Environment, environment: Environment,
securityProperties: CreSecurityProperties securityProperties: CreSecurityProperties
) : BaseSecurityConfig(userDetailsService, jwtService, environment, securityProperties) { ) : BaseSecurityConfig(userDetailsLogic, jwtLogic, environment, securityProperties) {
override val logger = KotlinLogging.logger {} override val logger = KotlinLogging.logger {}
init { 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.model.*
import dev.fyloz.colorrecipesexplorer.repository.CompanyRepository import dev.fyloz.colorrecipesexplorer.repository.CompanyRepository
import org.springframework.context.annotation.Lazy import org.springframework.context.annotation.Lazy
import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
interface CompanyService : interface CompanyLogic :
ExternalNamedModelService<Company, CompanySaveDto, CompanyUpdateDto, Company, CompanyRepository> { ExternalNamedModelService<Company, CompanySaveDto, CompanyUpdateDto, Company, CompanyRepository> {
/** Checks if the given [company] is used by one or more recipes. */ /** Checks if the given [company] is used by one or more recipes. */
fun isLinkedToRecipes(company: Company): Boolean fun isLinkedToRecipes(company: Company): Boolean
} }
@Service @Service
@Profile("!emergency") @RequireDatabase
class CompanyServiceImpl( class DefaultCompanyLogic(
companyRepository: CompanyRepository, companyRepository: CompanyRepository,
@Lazy val recipeService: RecipeService @Lazy val recipeLogic: RecipeLogic
) : ) :
AbstractExternalNamedModelService<Company, CompanySaveDto, CompanyUpdateDto, Company, CompanyRepository>( AbstractExternalNamedModelService<Company, CompanySaveDto, CompanyUpdateDto, Company, CompanyRepository>(
companyRepository companyRepository
), ),
CompanyService { CompanyLogic {
override fun idNotFoundException(id: Long) = companyIdNotFoundException(id) override fun idNotFoundException(id: Long) = companyIdNotFoundException(id)
override fun idAlreadyExistsException(id: Long) = companyIdAlreadyExistsException(id) override fun idAlreadyExistsException(id: Long) = companyIdAlreadyExistsException(id)
override fun nameNotFoundException(name: String) = companyNameNotFoundException(name) override fun nameNotFoundException(name: String) = companyNameNotFoundException(name)
@ -29,7 +29,7 @@ class CompanyServiceImpl(
override fun Company.toOutput() = this 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 { override fun update(entity: CompanyUpdateDto): Company {
// Lazy loaded to prevent checking the database when not necessary // 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.exception.RestException
import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.model.*
import dev.fyloz.colorrecipesexplorer.utils.mapMayThrow import dev.fyloz.colorrecipesexplorer.utils.mapMayThrow
import org.springframework.context.annotation.Profile
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import javax.transaction.Transactional import javax.transaction.Transactional
interface InventoryService { interface InventoryLogic {
/** Adds each given [MaterialQuantityDto] to the inventory and returns the updated quantities. */ /** Adds each given [MaterialQuantityDto] to the inventory and returns the updated quantities. */
fun add(materialQuantities: Collection<MaterialQuantityDto>): Collection<MaterialQuantityDto> fun add(materialQuantities: Collection<MaterialQuantityDto>): Collection<MaterialQuantityDto>
@ -26,11 +26,11 @@ interface InventoryService {
} }
@Service @Service
@Profile("!emergency") @RequireDatabase
class InventoryServiceImpl( class DefaultInventoryLogic(
private val materialService: MaterialService, private val materialLogic: MaterialLogic,
private val mixService: MixService private val mixLogic: MixLogic
) : InventoryService { ) : InventoryLogic {
@Transactional @Transactional
override fun add(materialQuantities: Collection<MaterialQuantityDto>) = override fun add(materialQuantities: Collection<MaterialQuantityDto>) =
materialQuantities.map { materialQuantities.map {
@ -38,14 +38,14 @@ class InventoryServiceImpl(
} }
override fun add(materialQuantity: MaterialQuantityDto) = override fun add(materialQuantity: MaterialQuantityDto) =
materialService.updateQuantity( materialLogic.updateQuantity(
materialService.getById(materialQuantity.material), materialLogic.getById(materialQuantity.material),
materialQuantity.quantity materialQuantity.quantity
) )
@Transactional @Transactional
override fun deductMix(mixRatio: MixDeductDto): Collection<MaterialQuantityDto> { 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 firstMixMaterial = mix.mixMaterials.first()
val adjustedFirstMaterialQuantity = firstMixMaterial.quantity * mixRatio.ratio val adjustedFirstMaterialQuantity = firstMixMaterial.quantity * mixRatio.ratio
@ -80,9 +80,9 @@ class InventoryServiceImpl(
} }
override fun deduct(materialQuantity: MaterialQuantityDto): Float = override fun deduct(materialQuantity: MaterialQuantityDto): Float =
with(materialService.getById(materialQuantity.material)) { with(materialLogic.getById(materialQuantity.material)) {
if (this.inventoryQuantity >= materialQuantity.quantity) { if (this.inventoryQuantity >= materialQuantity.quantity) {
materialService.updateQuantity(this, -materialQuantity.quantity) materialLogic.updateQuantity(this, -materialQuantity.quantity)
} else { } else {
throw NotEnoughInventoryException(materialQuantity.quantity, this) 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.model.*
import dev.fyloz.colorrecipesexplorer.repository.MaterialRepository import dev.fyloz.colorrecipesexplorer.repository.MaterialRepository
import dev.fyloz.colorrecipesexplorer.rest.FILE_CONTROLLER_PATH 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 io.jsonwebtoken.lang.Assert
import org.springframework.context.annotation.Lazy import org.springframework.context.annotation.Lazy
import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import java.net.URLEncoder import java.net.URLEncoder
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
interface MaterialService : interface MaterialLogic :
ExternalNamedModelService<Material, MaterialSaveDto, MaterialUpdateDto, MaterialOutputDto, MaterialRepository> { ExternalNamedModelService<Material, MaterialSaveDto, MaterialUpdateDto, MaterialOutputDto, MaterialRepository> {
/** Checks if a material with the given [materialType] exists. */ /** Checks if a material with the given [materialType] exists. */
fun existsByMaterialType(materialType: MaterialType): Boolean fun existsByMaterialType(materialType: MaterialType): Boolean
@ -34,19 +34,19 @@ interface MaterialService :
} }
@Service @Service
@Profile("!emergency") @RequireDatabase
class MaterialServiceImpl( class DefaultMaterialLogic(
materialRepository: MaterialRepository, materialRepository: MaterialRepository,
val recipeService: RecipeService, val recipeLogic: RecipeLogic,
val mixService: MixService, val mixLogic: MixLogic,
@Lazy val materialTypeService: MaterialTypeService, @Lazy val materialTypeLogic: MaterialTypeLogic,
val fileService: WriteableFileService, val fileService: WriteableFileLogic,
val configService: ConfigurationService val configService: ConfigurationLogic
) : ) :
AbstractExternalNamedModelService<Material, MaterialSaveDto, MaterialUpdateDto, MaterialOutputDto, MaterialRepository>( AbstractExternalNamedModelService<Material, MaterialSaveDto, MaterialUpdateDto, MaterialOutputDto, MaterialRepository>(
materialRepository materialRepository
), ),
MaterialService { MaterialLogic {
override fun idNotFoundException(id: Long) = materialIdNotFoundException(id) override fun idNotFoundException(id: Long) = materialIdNotFoundException(id)
override fun idAlreadyExistsException(id: Long) = materialIdAlreadyExistsException(id) override fun idAlreadyExistsException(id: Long) = materialIdAlreadyExistsException(id)
override fun nameNotFoundException(name: String) = materialNameNotFoundException(name) override fun nameNotFoundException(name: String) = materialNameNotFoundException(name)
@ -80,7 +80,7 @@ class MaterialServiceImpl(
material( material(
name = entity.name, name = entity.name,
inventoryQuantity = entity.inventoryQuantity, inventoryQuantity = entity.inventoryQuantity,
materialType = materialTypeService.getById(materialTypeId), materialType = materialTypeLogic.getById(materialTypeId),
isMixType = false isMixType = false
) )
}).apply { }).apply {
@ -102,7 +102,7 @@ class MaterialServiceImpl(
name = if (name != null && name.isNotBlank()) name else persistedMaterial.name, name = if (name != null && name.isNotBlank()) name else persistedMaterial.name,
inventoryQuantity = if (inventoryQuantity != null && inventoryQuantity != Float.MIN_VALUE) inventoryQuantity else persistedMaterial.inventoryQuantity, inventoryQuantity = if (inventoryQuantity != null && inventoryQuantity != Float.MIN_VALUE) inventoryQuantity else persistedMaterial.inventoryQuantity,
isMixType = persistedMaterial.isMixType, isMixType = persistedMaterial.isMixType,
materialType = if (materialTypeId != null) materialTypeService.getById(materialTypeId) else persistedMaterial.materialType materialType = if (materialTypeId != null) materialTypeLogic.getById(materialTypeId) else persistedMaterial.materialType
) )
}).apply { }).apply {
if (entity.simdutFile != null && !entity.simdutFile.isEmpty) fileService.write( if (entity.simdutFile != null && !entity.simdutFile.isEmpty) fileService.write(
@ -120,13 +120,13 @@ class MaterialServiceImpl(
} }
override fun getAllForMixCreation(recipeId: Long): Collection<MaterialOutputDto> { override fun getAllForMixCreation(recipeId: Long): Collection<MaterialOutputDto> {
val recipesMixTypes = recipeService.getById(recipeId).mixTypes val recipesMixTypes = recipeLogic.getById(recipeId).mixTypes
return getAllForOutput() return getAllForOutput()
.filter { !it.isMixType || recipesMixTypes.any { mixType -> mixType.material.id == it.id } } .filter { !it.isMixType || recipesMixTypes.any { mixType -> mixType.material.id == it.id } }
} }
override fun getAllForMixUpdate(mixId: Long): Collection<MaterialOutputDto> { override fun getAllForMixUpdate(mixId: Long): Collection<MaterialOutputDto> {
val mix = mixService.getById(mixId) val mix = mixLogic.getById(mixId)
val recipesMixTypes = mix.recipe.mixTypes val recipesMixTypes = mix.recipe.mixTypes
return getAllForOutput() return getAllForOutput()
.filter { !it.isMixType || recipesMixTypes.any { mixType -> mixType.material.id == it.id } } .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.*
import dev.fyloz.colorrecipesexplorer.model.validation.isNotNullAndNotBlank import dev.fyloz.colorrecipesexplorer.model.validation.isNotNullAndNotBlank
import dev.fyloz.colorrecipesexplorer.repository.MaterialTypeRepository import dev.fyloz.colorrecipesexplorer.repository.MaterialTypeRepository
import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
interface MaterialTypeService : interface MaterialTypeLogic :
ExternalNamedModelService<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialType, MaterialTypeRepository> { ExternalNamedModelService<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialType, MaterialTypeRepository> {
/** Checks if a material type with the given [prefix] exists. */ /** Checks if a material type with the given [prefix] exists. */
fun existsByPrefix(prefix: String): Boolean fun existsByPrefix(prefix: String): Boolean
@ -25,11 +25,11 @@ interface MaterialTypeService :
} }
@Service @Service
@Profile("!emergency") @RequireDatabase
class MaterialTypeServiceImpl(repository: MaterialTypeRepository, private val materialService: MaterialService) : class DefaultMaterialTypeLogic(repository: MaterialTypeRepository, private val materialLogic: MaterialLogic) :
AbstractExternalNamedModelService<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialType, MaterialTypeRepository>( AbstractExternalNamedModelService<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialType, MaterialTypeRepository>(
repository repository
), MaterialTypeService { ), MaterialTypeLogic {
override fun idNotFoundException(id: Long) = materialTypeIdNotFoundException(id) override fun idNotFoundException(id: Long) = materialTypeIdNotFoundException(id)
override fun idAlreadyExistsException(id: Long) = materialIdAlreadyExistsException(id) override fun idAlreadyExistsException(id: Long) = materialIdAlreadyExistsException(id)
override fun nameNotFoundException(name: String) = materialTypeNameNotFoundException(name) 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 existsByPrefix(prefix: String): Boolean = repository.existsByPrefix(prefix)
override fun isUsedByMaterial(materialType: MaterialType): Boolean = override fun isUsedByMaterial(materialType: MaterialType): Boolean =
materialService.existsByMaterialType(materialType) materialLogic.existsByMaterialType(materialType)
override fun getAllSystemTypes(): Collection<MaterialType> = repository.findAllBySystemTypeIs(true) override fun getAllSystemTypes(): Collection<MaterialType> = repository.findAllBySystemTypeIs(true)
override fun getAllNonSystemType(): Collection<MaterialType> = repository.findAllBySystemTypeIs(false) 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.model.*
import dev.fyloz.colorrecipesexplorer.repository.MixRepository import dev.fyloz.colorrecipesexplorer.repository.MixRepository
import dev.fyloz.colorrecipesexplorer.utils.setAll import dev.fyloz.colorrecipesexplorer.utils.setAll
import org.springframework.context.annotation.Lazy import org.springframework.context.annotation.Lazy
import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import javax.transaction.Transactional 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]. */ /** Gets all mixes with the given [mixType]. */
fun getAllByMixType(mixType: MixType): Collection<Mix> fun getAllByMixType(mixType: MixType): Collection<Mix>
@ -23,15 +23,15 @@ interface MixService : ExternalModelService<Mix, MixSaveDto, MixUpdateDto, MixOu
} }
@Service @Service
@Profile("!emergency") @RequireDatabase
class MixServiceImpl( class DefaultMixLogic(
mixRepository: MixRepository, mixRepository: MixRepository,
@Lazy val recipeService: RecipeService, @Lazy val recipeLogic: RecipeLogic,
@Lazy val materialTypeService: MaterialTypeService, @Lazy val materialTypeLogic: MaterialTypeLogic,
val mixMaterialService: MixMaterialService, val mixMaterialLogic: MixMaterialLogic,
val mixTypeService: MixTypeService val mixTypeLogic: MixTypeLogic
) : AbstractExternalModelService<Mix, MixSaveDto, MixUpdateDto, MixOutputDto, MixRepository>(mixRepository), ) : AbstractExternalModelService<Mix, MixSaveDto, MixUpdateDto, MixOutputDto, MixRepository>(mixRepository),
MixService { MixLogic {
override fun idNotFoundException(id: Long) = mixIdNotFoundException(id) override fun idNotFoundException(id: Long) = mixIdNotFoundException(id)
override fun idAlreadyExistsException(id: Long) = mixIdAlreadyExistsException(id) override fun idAlreadyExistsException(id: Long) = mixIdAlreadyExistsException(id)
@ -43,7 +43,7 @@ class MixServiceImpl(
this.location, this.location,
this.mixType, this.mixType,
this.mixMaterials.map { this.mixMaterials.map {
with(mixMaterialService) { with(mixMaterialLogic) {
return@with it.toOutput() return@with it.toOutput()
} }
}.toSet() }.toSet()
@ -51,17 +51,17 @@ class MixServiceImpl(
@Transactional @Transactional
override fun save(entity: MixSaveDto): Mix { override fun save(entity: MixSaveDto): Mix {
val recipe = recipeService.getById(entity.recipeId) val recipe = recipeLogic.getById(entity.recipeId)
val materialType = materialTypeService.getById(entity.materialTypeId) val materialType = materialTypeLogic.getById(entity.materialTypeId)
val mixType = mixTypeService.getOrCreateForNameAndMaterialType(entity.name, materialType) val mixType = mixTypeLogic.getOrCreateForNameAndMaterialType(entity.name, materialType)
val mixMaterials = if (entity.mixMaterials != null) mixMaterialService.create(entity.mixMaterials) else setOf() val mixMaterials = if (entity.mixMaterials != null) mixMaterialLogic.create(entity.mixMaterials) else setOf()
mixMaterialService.validateMixMaterials(mixMaterials) mixMaterialLogic.validateMixMaterials(mixMaterials)
var mix = mix(recipe = recipe, mixType = mixType, mixMaterials = mixMaterials.toMutableSet()) var mix = mix(recipe = recipe, mixType = mixType, mixMaterials = mixMaterials.toMutableSet())
mix = save(mix) mix = save(mix)
recipeService.addMix(recipe, mix) recipeLogic.addMix(recipe, mix)
return mix return mix
} }
@ -72,18 +72,18 @@ class MixServiceImpl(
if (entity.name != null || entity.materialTypeId != null) { if (entity.name != null || entity.materialTypeId != null) {
val name = entity.name ?: mix.mixType.name val name = entity.name ?: mix.mixType.name
val materialType = if (entity.materialTypeId != null) val materialType = if (entity.materialTypeId != null)
materialTypeService.getById(entity.materialTypeId) materialTypeLogic.getById(entity.materialTypeId)
else else
mix.mixType.material.materialType!! mix.mixType.material.materialType!!
mix.mixType = if (mixTypeIsShared(mix.mixType)) { mix.mixType = if (mixTypeIsShared(mix.mixType)) {
mixTypeService.saveForNameAndMaterialType(name, materialType) mixTypeLogic.saveForNameAndMaterialType(name, materialType)
} else { } else {
mixTypeService.updateForNameAndMaterialType(mix.mixType, name, materialType) mixTypeLogic.updateForNameAndMaterialType(mix.mixType, name, materialType)
} }
} }
if (entity.mixMaterials != null) { if (entity.mixMaterials != null) {
mix.mixMaterials.setAll(mixMaterialService.create(entity.mixMaterials!!).toMutableSet()) mix.mixMaterials.setAll(mixMaterialLogic.create(entity.mixMaterials!!).toMutableSet())
} }
return update(mix) return update(mix)
} }
@ -99,7 +99,7 @@ class MixServiceImpl(
@Transactional @Transactional
override fun delete(entity: Mix) { override fun delete(entity: Mix) {
if (!repository.canBeDeleted(entity.id!!)) throw cannotDeleteMixException(entity) if (!repository.canBeDeleted(entity.id!!)) throw cannotDeleteMixException(entity)
recipeService.removeMix(entity) recipeLogic.removeMix(entity)
super.delete(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.exception.RestException
import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.model.*
@ -10,7 +10,7 @@ import org.springframework.context.annotation.Profile
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service 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]. */ /** Checks if one or more mix materials have the given [material]. */
fun existsByMaterial(material: Material): Boolean fun existsByMaterial(material: Material): Boolean
@ -35,16 +35,16 @@ interface MixMaterialService : ModelService<MixMaterial, MixMaterialRepository>
@Service @Service
@Profile("!emergency") @Profile("!emergency")
class MixMaterialServiceImpl( class DefaultMixMaterialLogic(
mixMaterialRepository: MixMaterialRepository, mixMaterialRepository: MixMaterialRepository,
@Lazy val materialService: MaterialService @Lazy val materialLogic: MaterialLogic
) : AbstractModelService<MixMaterial, MixMaterialRepository>(mixMaterialRepository), MixMaterialService { ) : AbstractModelService<MixMaterial, MixMaterialRepository>(mixMaterialRepository), MixMaterialLogic {
override fun idNotFoundException(id: Long) = mixMaterialIdNotFoundException(id) override fun idNotFoundException(id: Long) = mixMaterialIdNotFoundException(id)
override fun idAlreadyExistsException(id: Long) = mixMaterialIdAlreadyExistsException(id) override fun idAlreadyExistsException(id: Long) = mixMaterialIdAlreadyExistsException(id)
override fun MixMaterial.toOutput() = MixMaterialOutputDto( override fun MixMaterial.toOutput() = MixMaterialOutputDto(
this.id!!, this.id!!,
with(materialService) { this@toOutput.material.toOutput() }, with(materialLogic) { this@toOutput.material.toOutput() },
this.quantity, this.quantity,
this.position this.position
) )
@ -55,7 +55,7 @@ class MixMaterialServiceImpl(
override fun create(mixMaterial: MixMaterialDto): MixMaterial = override fun create(mixMaterial: MixMaterialDto): MixMaterial =
mixMaterial( mixMaterial(
material = materialService.getById(mixMaterial.materialId), material = materialLogic.getById(mixMaterial.materialId),
quantity = mixMaterial.quantity, quantity = mixMaterial.quantity,
position = mixMaterial.position 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.model.*
import dev.fyloz.colorrecipesexplorer.repository.MixTypeRepository import dev.fyloz.colorrecipesexplorer.repository.MixTypeRepository
import org.springframework.context.annotation.Lazy import org.springframework.context.annotation.Lazy
import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Service 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. */ /** Checks if a [MixType] with the given [name] and [materialType] exists. */
fun existsByNameAndMaterialType(name: String, materialType: MaterialType): Boolean fun existsByNameAndMaterialType(name: String, materialType: MaterialType): Boolean
@ -27,13 +27,12 @@ interface MixTypeService : NamedModelService<MixType, MixTypeRepository> {
} }
@Service @Service
@Profile("!emergency") @RequireDatabase
class MixTypeServiceImpl( class DefaultMixTypeLogic(
mixTypeRepository: MixTypeRepository, mixTypeRepository: MixTypeRepository,
@Lazy val materialService: MaterialService, @Lazy val materialLogic: MaterialLogic
@Lazy val mixService: MixService
) : ) :
AbstractNamedModelService<MixType, MixTypeRepository>(mixTypeRepository), MixTypeService { AbstractNamedModelService<MixType, MixTypeRepository>(mixTypeRepository), MixTypeLogic {
override fun idNotFoundException(id: Long) = mixTypeIdNotFoundException(id) override fun idNotFoundException(id: Long) = mixTypeIdNotFoundException(id)
override fun idAlreadyExistsException(id: Long) = mixTypeIdAlreadyExistsException(id) override fun idAlreadyExistsException(id: Long) = mixTypeIdAlreadyExistsException(id)
override fun nameNotFoundException(name: String) = mixTypeNameNotFoundException(name) override fun nameNotFoundException(name: String) = mixTypeNameNotFoundException(name)
@ -56,7 +55,7 @@ class MixTypeServiceImpl(
saveForNameAndMaterialType(name, materialType) saveForNameAndMaterialType(name, materialType)
override fun save(entity: MixType): MixType { override fun save(entity: MixType): MixType {
if (materialService.existsByName(entity.name)) if (materialLogic.existsByName(entity.name))
throw materialNameAlreadyExistsException(entity.name) throw materialNameAlreadyExistsException(entity.name)
return super.save(entity) 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.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.*
import dev.fyloz.colorrecipesexplorer.model.account.Group import dev.fyloz.colorrecipesexplorer.model.account.Group
import dev.fyloz.colorrecipesexplorer.model.validation.or import dev.fyloz.colorrecipesexplorer.model.validation.or
import dev.fyloz.colorrecipesexplorer.repository.RecipeRepository 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 dev.fyloz.colorrecipesexplorer.utils.setAll
import org.springframework.context.annotation.Lazy import org.springframework.context.annotation.Lazy
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
@ -16,7 +16,7 @@ import java.time.LocalDate
import java.time.Period import java.time.Period
import javax.transaction.Transactional import javax.transaction.Transactional
interface RecipeService : interface RecipeLogic :
ExternalModelService<Recipe, RecipeSaveDto, RecipeUpdateDto, RecipeOutputDto, RecipeRepository> { ExternalModelService<Recipe, RecipeSaveDto, RecipeUpdateDto, RecipeOutputDto, RecipeRepository> {
/** Checks if one or more recipes have the given [company]. */ /** Checks if one or more recipes have the given [company]. */
fun existsByCompany(company: Company): Boolean fun existsByCompany(company: Company): Boolean
@ -45,19 +45,19 @@ interface RecipeService :
@Service @Service
@RequireDatabase @RequireDatabase
class RecipeServiceImpl( class DefaultRecipeLogic(
recipeRepository: RecipeRepository, recipeRepository: RecipeRepository,
val companyService: CompanyService, val companyLogic: CompanyLogic,
val mixService: MixService, val mixLogic: MixLogic,
val recipeStepService: RecipeStepService, val recipeStepLogic: RecipeStepLogic,
@Lazy val groupService: GroupService, @Lazy val groupLogic: GroupLogic,
val recipeImageService: RecipeImageService, val recipeImageLogic: RecipeImageLogic,
val configService: ConfigurationService val configService: ConfigurationLogic
) : ) :
AbstractExternalModelService<Recipe, RecipeSaveDto, RecipeUpdateDto, RecipeOutputDto, RecipeRepository>( AbstractExternalModelService<Recipe, RecipeSaveDto, RecipeUpdateDto, RecipeOutputDto, RecipeRepository>(
recipeRepository recipeRepository
), ),
RecipeService { RecipeLogic {
override fun idNotFoundException(id: Long) = recipeIdNotFoundException(id) override fun idNotFoundException(id: Long) = recipeIdNotFoundException(id)
override fun idAlreadyExistsException(id: Long) = recipeIdAlreadyExistsException(id) override fun idAlreadyExistsException(id: Long) = recipeIdAlreadyExistsException(id)
@ -73,12 +73,12 @@ class RecipeServiceImpl(
this.remark, this.remark,
this.company, this.company,
this.mixes.map { this.mixes.map {
with(mixService) { with(mixLogic) {
it.toOutput() it.toOutput()
} }
}.toSet(), }.toSet(),
this.groupsInformation, this.groupsInformation,
recipeImageService.getAllImages(this) recipeImageLogic.getAllImages(this)
.map { this.imageUrl(configService.getContent(ConfigurationType.INSTANCE_URL), it) } .map { this.imageUrl(configService.getContent(ConfigurationType.INSTANCE_URL), it) }
.toSet() .toSet()
) )
@ -96,7 +96,7 @@ class RecipeServiceImpl(
override fun getAllByCompany(company: Company) = repository.findAllByCompany(company) override fun getAllByCompany(company: Company) = repository.findAllByCompany(company)
override fun save(entity: RecipeSaveDto): Recipe { override fun save(entity: RecipeSaveDto): Recipe {
val company = companyService.getById(entity.companyId) val company = companyLogic.getById(entity.companyId)
if (existsByNameAndCompany(entity.name, company)) { if (existsByNameAndCompany(entity.name, company)) {
throw recipeNameAlreadyExistsForCompanyException(entity.name, company) throw recipeNameAlreadyExistsForCompanyException(entity.name, company)
@ -160,12 +160,12 @@ class RecipeServiceImpl(
this.steps = it.steps.toMutableSet() this.steps = it.steps.toMutableSet()
} }
} ?: recipeGroupInformation( } ?: recipeGroupInformation(
group = groupService.getById(it.groupId), group = groupLogic.getById(it.groupId),
steps = it.steps.toMutableSet() steps = it.steps.toMutableSet()
) )
updatedGroupsInformation.add(updatedGroupInformation) updatedGroupsInformation.add(updatedGroupInformation)
recipeStepService.validateGroupInformationSteps(updatedGroupInformation) recipeStepLogic.validateGroupInformationSteps(updatedGroupInformation)
} }
} }
@ -192,7 +192,7 @@ class RecipeServiceImpl(
} }
if (publicDataDto.mixesLocation != null) { 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) }) 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]. */ /** Gets the name of every images associated to the recipe with the given [recipe]. */
fun getAllImages(recipe: Recipe): Set<String> fun getAllImages(recipe: Recipe): Set<String>
@ -219,9 +219,9 @@ const val RECIPE_IMAGE_EXTENSION = ".jpg"
@Service @Service
@RequireDatabase @RequireDatabase
class RecipeImageServiceImpl( class DefaultRecipeImageLogic(
val fileService: WriteableFileService val fileService: WriteableFileLogic
) : RecipeImageService { ) : RecipeImageLogic {
override fun getAllImages(recipe: Recipe) = override fun getAllImages(recipe: Recipe) =
fileService.listDirectoryFiles(recipe.imagesDirectoryPath) fileService.listDirectoryFiles(recipe.imagesDirectoryPath)
.map { it.name } .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.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.account.Group
import dev.fyloz.colorrecipesexplorer.model.recipeStepIdAlreadyExistsException
import dev.fyloz.colorrecipesexplorer.model.recipeStepIdNotFoundException
import dev.fyloz.colorrecipesexplorer.repository.RecipeStepRepository import dev.fyloz.colorrecipesexplorer.repository.RecipeStepRepository
import dev.fyloz.colorrecipesexplorer.utils.findDuplicated import dev.fyloz.colorrecipesexplorer.utils.findDuplicated
import dev.fyloz.colorrecipesexplorer.utils.hasGaps import dev.fyloz.colorrecipesexplorer.utils.hasGaps
import org.springframework.context.annotation.Profile
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service 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]. */ /** Validates the steps of the given [groupInformation], according to the criteria of [validateSteps]. */
fun validateGroupInformationSteps(groupInformation: RecipeGroupInformation) fun validateGroupInformationSteps(groupInformation: RecipeGroupInformation)
@ -23,10 +26,10 @@ interface RecipeStepService : ModelService<RecipeStep, RecipeStepRepository> {
} }
@Service @Service
@Profile("!emergency") @RequireDatabase
class RecipeStepServiceImpl(recipeStepRepository: RecipeStepRepository) : class DefaultRecipeStepLogic(recipeStepRepository: RecipeStepRepository) :
AbstractModelService<RecipeStep, RecipeStepRepository>(recipeStepRepository), AbstractModelService<RecipeStep, RecipeStepRepository>(recipeStepRepository),
RecipeStepService { RecipeStepLogic {
override fun idNotFoundException(id: Long) = recipeStepIdNotFoundException(id) override fun idNotFoundException(id: Long) = recipeStepIdNotFoundException(id)
override fun idAlreadyExistsException(id: Long) = recipeStepIdAlreadyExistsException(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.AlreadyExistsException
import dev.fyloz.colorrecipesexplorer.exception.NotFoundException 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.ConfigurationType
import dev.fyloz.colorrecipesexplorer.model.touchupkit.* import dev.fyloz.colorrecipesexplorer.model.touchupkit.*
import dev.fyloz.colorrecipesexplorer.repository.TouchUpKitRepository import dev.fyloz.colorrecipesexplorer.repository.TouchUpKitRepository
import dev.fyloz.colorrecipesexplorer.rest.TOUCH_UP_KIT_CONTROLLER_PATH 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 dev.fyloz.colorrecipesexplorer.utils.*
import org.springframework.context.annotation.Profile
import org.springframework.core.io.ByteArrayResource import org.springframework.core.io.ByteArrayResource
import org.springframework.core.io.Resource import org.springframework.core.io.Resource
import org.springframework.stereotype.Service 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_FR = "KIT DE RETOUCHE"
const val TOUCH_UP_TEXT_EN = "TOUCH UP KIT" const val TOUCH_UP_TEXT_EN = "TOUCH UP KIT"
interface TouchUpKitService : interface TouchUpKitLogic :
ExternalModelService<TouchUpKit, TouchUpKitSaveDto, TouchUpKitUpdateDto, TouchUpKitOutputDto, TouchUpKitRepository> { ExternalModelService<TouchUpKit, TouchUpKitSaveDto, TouchUpKitUpdateDto, TouchUpKitOutputDto, TouchUpKitRepository> {
fun isExpired(touchUpKit: TouchUpKit): Boolean fun isExpired(touchUpKit: TouchUpKit): Boolean
@ -42,14 +41,14 @@ interface TouchUpKitService :
} }
@Service @Service
@Profile("!emergency") @RequireDatabase
class TouchUpKitServiceImpl( class DefaultTouchUpKitLogic(
private val fileService: WriteableFileService, private val fileService: WriteableFileLogic,
private val configService: ConfigurationService, private val configService: ConfigurationLogic,
touchUpKitRepository: TouchUpKitRepository touchUpKitRepository: TouchUpKitRepository
) : AbstractExternalModelService<TouchUpKit, TouchUpKitSaveDto, TouchUpKitUpdateDto, TouchUpKitOutputDto, TouchUpKitRepository>( ) : AbstractExternalModelService<TouchUpKit, TouchUpKitSaveDto, TouchUpKitUpdateDto, TouchUpKitOutputDto, TouchUpKitRepository>(
touchUpKitRepository touchUpKitRepository
), TouchUpKitService { ), TouchUpKitLogic {
private val cacheGeneratedFiles by lazy { private val cacheGeneratedFiles by lazy {
configService.getContent(ConfigurationType.TOUCH_UP_KIT_CACHE_PDF) == true.toString() 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.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.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.decrypt
import dev.fyloz.colorrecipesexplorer.utils.encrypt import dev.fyloz.colorrecipesexplorer.utils.encrypt
import org.slf4j.Logger import mu.KotlinLogging
import org.springframework.context.annotation.Lazy import org.springframework.context.annotation.Lazy
import org.springframework.core.io.Resource import org.springframework.core.io.Resource
import org.springframework.security.crypto.keygen.KeyGenerators import org.springframework.security.crypto.keygen.KeyGenerators
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import org.springframework.web.multipart.MultipartFile import org.springframework.web.multipart.MultipartFile
interface ConfigurationService { interface ConfigurationLogic {
/** Gets all set configurations. */ /** Gets all set configurations. */
fun getAll(): List<ConfigurationBase> fun getAll(): List<ConfigurationBase>
@ -73,13 +73,13 @@ const val CONFIGURATION_ICON_FILE_PATH = "images/icon"
const val CONFIGURATION_FORMATTED_LIST_DELIMITER = ';' const val CONFIGURATION_FORMATTED_LIST_DELIMITER = ';'
@Service("configurationService") @Service("configurationService")
class ConfigurationServiceImpl( class DefaultConfigurationLogic(
@Lazy private val fileService: WriteableFileService, @Lazy private val fileService: WriteableFileLogic,
private val resourceFileService: ResourceFileService, private val resourceFileService: ResourceFileLogic,
private val configurationSource: ConfigurationSource, private val configurationSource: ConfigurationSource,
private val securityProperties: CreSecurityProperties, private val securityProperties: CreSecurityProperties
private val logger: Logger ) : ConfigurationLogic {
) : ConfigurationService { private val logger = KotlinLogging.logger { }
private val saltConfigurationType = ConfigurationType.GENERATED_ENCRYPTION_SALT private val saltConfigurationType = ConfigurationType.GENERATED_ENCRYPTION_SALT
private val encryptionSalt by lazy { private val encryptionSalt by lazy {
securityProperties.configSalt ?: getGeneratedSalt() 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.JavaFile
import dev.fyloz.colorrecipesexplorer.SUPPORTED_DATABASE_VERSION 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.repository.ConfigurationRepository
import dev.fyloz.colorrecipesexplorer.utils.create import dev.fyloz.colorrecipesexplorer.utils.create
import dev.fyloz.colorrecipesexplorer.utils.excludeAll import dev.fyloz.colorrecipesexplorer.utils.excludeAll
import org.slf4j.Logger import mu.KotlinLogging
import org.springframework.boot.info.BuildProperties import org.springframework.boot.info.BuildProperties
import org.springframework.context.annotation.Lazy import org.springframework.context.annotation.Lazy
import org.springframework.data.repository.findByIdOrNull import org.springframework.data.repository.findByIdOrNull
@ -36,9 +36,9 @@ interface ConfigurationSource {
class CompositeConfigurationSource( class CompositeConfigurationSource(
@Lazy private val configurationRepository: ConfigurationRepository, @Lazy private val configurationRepository: ConfigurationRepository,
private val properties: CreProperties, private val properties: CreProperties,
private val buildInfo: BuildProperties, private val buildInfo: BuildProperties
private val logger: Logger
) : ConfigurationSource { ) : ConfigurationSource {
private val logger = KotlinLogging.logger {}
private val repository by lazy { RepositoryConfigurationSource(configurationRepository) } private val repository by lazy { RepositoryConfigurationSource(configurationRepository) }
private val file by lazy { private val file by lazy {
FileConfigurationSource("${properties.configDirectory}/$CONFIGURATION_FILE_PATH") 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.JavaFile
import dev.fyloz.colorrecipesexplorer.utils.File 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.config.properties.CreProperties
import dev.fyloz.colorrecipesexplorer.exception.RestException 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. */ /** Checks if the file at the given [path] exists. */
fun exists(path: String): Boolean fun exists(path: String): Boolean
@ -35,7 +35,7 @@ interface FileService {
fun fullPath(path: String): FilePath fun fullPath(path: String): FilePath
} }
interface WriteableFileService : FileService { interface WriteableFileLogic : FileLogic {
/** Creates a file at the given [path]. */ /** Creates a file at the given [path]. */
fun create(path: String) fun create(path: String)
@ -56,10 +56,10 @@ interface WriteableFileService : FileService {
} }
@Service @Service
class FileServiceImpl( class DefaultFileLogic(
private val fileCache: FileCache, private val fileCache: FileCache,
private val creProperties: CreProperties private val creProperties: CreProperties
) : WriteableFileService { ) : WriteableFileLogic {
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
override fun exists(path: String): Boolean { 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 dev.fyloz.colorrecipesexplorer.utils.FilePath
import org.springframework.core.io.Resource import org.springframework.core.io.Resource
@ -6,9 +6,9 @@ import org.springframework.core.io.ResourceLoader
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
@Service @Service
class ResourceFileService( class ResourceFileLogic(
private val resourceLoader: ResourceLoader private val resourceLoader: ResourceLoader
) : FileService { ) : FileLogic {
override fun exists(path: String) = override fun exists(path: String) =
fullPath(path).resource.exists() 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 mu.KotlinLogging
import org.springframework.context.annotation.Profile import org.springframework.context.annotation.Profile
import org.springframework.scheduling.annotation.Scheduled import org.springframework.scheduling.annotation.Scheduled
@ -9,7 +9,7 @@ import org.springframework.stereotype.Component
@Component @Component
@Profile("!emergency") @Profile("!emergency")
class TouchUpKitRemover( class TouchUpKitRemover(
private val touchUpKitService: TouchUpKitService private val touchUpKitLogic: TouchUpKitLogic
) { ) {
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
@ -20,10 +20,10 @@ class TouchUpKitRemover(
} }
private fun removeExpiredKits() { private fun removeExpiredKits() {
with(touchUpKitService.getAll().filter(touchUpKitService::isExpired)) { with(touchUpKitLogic.getAll().filter(touchUpKitLogic::isExpired)) {
this.forEach { this.forEach {
logger.debug("Removed expired touch up kit ${it.id} (${it.project} ${it.buggy})") 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") 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.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.model.account.*
import dev.fyloz.colorrecipesexplorer.repository.GroupRepository 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.context.annotation.Profile
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import org.springframework.web.util.WebUtils import org.springframework.web.util.WebUtils
@ -14,7 +14,7 @@ import javax.transaction.Transactional
const val defaultGroupCookieMaxAge = 10 * 365 * 24 * 60 * 60 // 10 ans const val defaultGroupCookieMaxAge = 10 * 365 * 24 * 60 * 60 // 10 ans
interface GroupService : interface GroupLogic :
ExternalNamedModelService<Group, GroupSaveDto, GroupUpdateDto, GroupOutputDto, GroupRepository> { ExternalNamedModelService<Group, GroupSaveDto, GroupUpdateDto, GroupOutputDto, GroupRepository> {
/** Gets all the users of the group with the given [id]. */ /** Gets all the users of the group with the given [id]. */
fun getUsersForGroup(id: Long): Collection<User> fun getUsersForGroup(id: Long): Collection<User>
@ -28,13 +28,13 @@ interface GroupService :
@Service @Service
@Profile("!emergency") @Profile("!emergency")
class GroupServiceImpl( class DefaultGroupLogic(
private val userService: UserService, private val userLogic: UserLogic,
groupRepository: GroupRepository groupRepository: GroupRepository
) : AbstractExternalNamedModelService<Group, GroupSaveDto, GroupUpdateDto, GroupOutputDto, GroupRepository>( ) : AbstractExternalNamedModelService<Group, GroupSaveDto, GroupUpdateDto, GroupOutputDto, GroupRepository>(
groupRepository groupRepository
), ),
GroupService { GroupLogic {
override fun idNotFoundException(id: Long) = groupIdNotFoundException(id) override fun idNotFoundException(id: Long) = groupIdNotFoundException(id)
override fun idAlreadyExistsException(id: Long) = groupIdAlreadyExistsException(id) override fun idAlreadyExistsException(id: Long) = groupIdAlreadyExistsException(id)
override fun nameNotFoundException(name: String) = groupNameNotFoundException(name) override fun nameNotFoundException(name: String) = groupNameNotFoundException(name)
@ -49,12 +49,12 @@ class GroupServiceImpl(
override fun existsByName(name: String): Boolean = repository.existsByName(name) override fun existsByName(name: String): Boolean = repository.existsByName(name)
override fun getUsersForGroup(id: Long): Collection<User> = override fun getUsersForGroup(id: Long): Collection<User> =
userService.getByGroup(getById(id)) userLogic.getByGroup(getById(id))
@Transactional @Transactional
override fun save(entity: Group): Group { override fun save(entity: Group): Group {
return super<AbstractExternalNamedModelService>.save(entity).apply { return super<AbstractExternalNamedModelService>.save(entity).apply {
userService.saveDefaultGroupUser(this) userLogic.saveDefaultGroupUser(this)
} }
} }
@ -71,14 +71,14 @@ class GroupServiceImpl(
@Transactional @Transactional
override fun delete(entity: Group) { override fun delete(entity: Group) {
userService.delete(userService.getDefaultGroupUser(entity)) userLogic.delete(userLogic.getDefaultGroupUser(entity))
super.delete(entity) super.delete(entity)
} }
override fun getRequestDefaultGroup(request: HttpServletRequest): Group { override fun getRequestDefaultGroup(request: HttpServletRequest): Group {
val defaultGroupCookie = WebUtils.getCookie(request, defaultGroupCookieName) val defaultGroupCookie = WebUtils.getCookie(request, defaultGroupCookieName)
?: throw NoDefaultGroupException() ?: throw NoDefaultGroupException()
val defaultGroupUser = userService.getById( val defaultGroupUser = userLogic.getById(
defaultGroupCookie.value.toLong(), defaultGroupCookie.value.toLong(),
ignoreDefaultGroupUsers = false, ignoreDefaultGroupUsers = false,
ignoreSystemUsers = true ignoreSystemUsers = true
@ -88,7 +88,7 @@ class GroupServiceImpl(
override fun setResponseDefaultGroup(groupId: Long, response: HttpServletResponse) { override fun setResponseDefaultGroup(groupId: Long, response: HttpServletResponse) {
val group = getById(groupId) val group = getById(groupId)
val defaultGroupUser = userService.getDefaultGroupUser(group) val defaultGroupUser = userLogic.getDefaultGroupUser(group)
response.addHeader( response.addHeader(
"Set-Cookie", "Set-Cookie",
"$defaultGroupCookieName=${defaultGroupUser.id}; Max-Age=$defaultGroupCookieMaxAge; Path=/api; HttpOnly; Secure; SameSite=strict" "$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.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue import com.fasterxml.jackson.module.kotlin.readValue
@ -18,7 +18,7 @@ import java.util.*
const val jwtClaimUser = "user" const val jwtClaimUser = "user"
interface JwtService { interface JwtLogic {
/** Build a JWT token for the given [userDetails]. */ /** Build a JWT token for the given [userDetails]. */
fun buildJwt(userDetails: UserDetails): String fun buildJwt(userDetails: UserDetails): String
@ -30,10 +30,10 @@ interface JwtService {
} }
@Service @Service
class JwtServiceImpl( class DefaultJwtLogic(
val objectMapper: ObjectMapper, val objectMapper: ObjectMapper,
val securityProperties: CreSecurityProperties val securityProperties: CreSecurityProperties
) : JwtService { ) : JwtLogic {
private val secretKey by lazy { private val secretKey by lazy {
securityProperties.jwtSecret.base64encode() 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.SpringUserDetails
import dev.fyloz.colorrecipesexplorer.SpringUserDetailsService import dev.fyloz.colorrecipesexplorer.SpringUserDetailsService
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties
import dev.fyloz.colorrecipesexplorer.exception.NotFoundException import dev.fyloz.colorrecipesexplorer.exception.NotFoundException
import dev.fyloz.colorrecipesexplorer.model.account.Permission 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.security.core.userdetails.UsernameNotFoundException
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
interface UserDetailsService : SpringUserDetailsService { interface UserDetailsLogic : SpringUserDetailsService {
/** Loads an [User] for the given [id]. */ /** Loads an [User] for the given [id]. */
fun loadUserById(id: Long, ignoreDefaultGroupUsers: Boolean = false): UserDetails fun loadUserById(id: Long, ignoreDefaultGroupUsers: Boolean = false): UserDetails
} }
@Service @Service
@Profile("!emergency") @RequireDatabase
class UserDetailsServiceImpl( class DefaultUserDetailsLogic(
private val userService: UserService private val userLogic: UserLogic
) : UserDetailsService { ) : UserDetailsLogic {
override fun loadUserByUsername(username: String): UserDetails { override fun loadUserByUsername(username: String): UserDetails {
try { try {
return loadUserById(username.toLong(), true) return loadUserById(username.toLong(), true)
@ -31,7 +32,7 @@ class UserDetailsServiceImpl(
} }
override fun loadUserById(id: Long, ignoreDefaultGroupUsers: Boolean): UserDetails { override fun loadUserById(id: Long, ignoreDefaultGroupUsers: Boolean): UserDetails {
val user = userService.getById( val user = userLogic.getById(
id, id,
ignoreDefaultGroupUsers = ignoreDefaultGroupUsers, ignoreDefaultGroupUsers = ignoreDefaultGroupUsers,
ignoreSystemUsers = false ignoreSystemUsers = false
@ -42,9 +43,9 @@ class UserDetailsServiceImpl(
@Service @Service
@Profile("emergency") @Profile("emergency")
class EmergencyUserDetailsServiceImpl( class EmergencyUserDetailsLogic(
securityProperties: CreSecurityProperties securityProperties: CreSecurityProperties
) : UserDetailsService { ) : UserDetailsLogic {
private val users: Set<User> private val users: Set<User>
init { 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.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.account.*
import dev.fyloz.colorrecipesexplorer.model.validation.or import dev.fyloz.colorrecipesexplorer.model.validation.or
import dev.fyloz.colorrecipesexplorer.repository.UserRepository 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.Lazy
import org.springframework.context.annotation.Profile import org.springframework.context.annotation.Profile
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import org.springframework.web.util.WebUtils import org.springframework.web.util.WebUtils
import java.time.LocalDateTime import java.time.LocalDateTime
import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletRequest
interface UserService : interface UserLogic :
ExternalModelService<User, UserSaveDto, UserUpdateDto, UserOutputDto, UserRepository> { ExternalModelService<User, UserSaveDto, UserUpdateDto, UserOutputDto, UserRepository> {
/** Check if an [User] with the given [firstName] and [lastName] exists. */ /** Check if an [User] with the given [firstName] and [lastName] exists. */
fun existsByFirstNameAndLastName(firstName: String, lastName: String): Boolean fun existsByFirstNameAndLastName(firstName: String, lastName: String): Boolean
@ -52,13 +51,13 @@ interface UserService :
@Service @Service
@Profile("!emergency") @Profile("!emergency")
class UserServiceImpl( class DefaultUserLogic(
userRepository: UserRepository, userRepository: UserRepository,
@Lazy val groupService: GroupService, @Lazy val groupLogic: GroupLogic,
) : AbstractExternalModelService<User, UserSaveDto, UserUpdateDto, UserOutputDto, UserRepository>( ) : AbstractExternalModelService<User, UserSaveDto, UserUpdateDto, UserOutputDto, UserRepository>(
userRepository userRepository
), ),
UserService { UserLogic {
override fun idNotFoundException(id: Long) = userIdNotFoundException(id) override fun idNotFoundException(id: Long) = userIdNotFoundException(id)
override fun idAlreadyExistsException(id: Long) = userIdAlreadyExistsException(id) override fun idAlreadyExistsException(id: Long) = userIdAlreadyExistsException(id)
@ -96,7 +95,7 @@ class UserServiceImpl(
plainPassword = password, plainPassword = password,
isDefaultGroupUser = false, isDefaultGroupUser = false,
isSystemUser = false, isSystemUser = false,
group = if (groupId != null) groupService.getById(groupId) else null, group = if (groupId != null) groupLogic.getById(groupId) else null,
permissions = permissions permissions = permissions
) )
}) })
@ -142,7 +141,7 @@ class UserServiceImpl(
password = persistedUser.password, password = persistedUser.password,
isDefaultGroupUser = false, isDefaultGroupUser = false,
isSystemUser = 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, permissions = permissions?.toMutableSet() ?: persistedUser.permissions,
lastLoginTime = persistedUser.lastLoginTime 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.PreAuthorizeEditUsers
import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeViewUsers 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.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.context.annotation.Profile
import org.springframework.http.MediaType import org.springframework.http.MediaType
import org.springframework.security.access.prepost.PreAuthorize import org.springframework.security.access.prepost.PreAuthorize
@ -20,22 +19,22 @@ private const val GROUP_CONTROLLER_PATH = "api/user/group"
@RestController @RestController
@RequestMapping(USER_CONTROLLER_PATH) @RequestMapping(USER_CONTROLLER_PATH)
@Profile("!emergency") @Profile("!emergency")
class UserController(private val userService: UserService) { class UserController(private val userLogic: UserLogic) {
@GetMapping @GetMapping
@PreAuthorizeViewUsers @PreAuthorizeViewUsers
fun getAll() = fun getAll() =
ok(userService.getAllForOutput()) ok(userLogic.getAllForOutput())
@GetMapping("{id}") @GetMapping("{id}")
@PreAuthorizeViewUsers @PreAuthorizeViewUsers
fun getById(@PathVariable id: Long) = fun getById(@PathVariable id: Long) =
ok(userService.getByIdForOutput(id)) ok(userLogic.getByIdForOutput(id))
@PostMapping @PostMapping
@PreAuthorizeEditUsers @PreAuthorizeEditUsers
fun save(@Valid @RequestBody user: UserSaveDto) = fun save(@Valid @RequestBody user: UserSaveDto) =
created<UserOutputDto>(USER_CONTROLLER_PATH) { created<UserOutputDto>(USER_CONTROLLER_PATH) {
with(userService) { with(userLogic) {
save(user).toOutput() save(user).toOutput()
} }
} }
@ -44,14 +43,14 @@ class UserController(private val userService: UserService) {
@PreAuthorizeEditUsers @PreAuthorizeEditUsers
fun update(@Valid @RequestBody user: UserUpdateDto) = fun update(@Valid @RequestBody user: UserUpdateDto) =
noContent { noContent {
userService.update(user) userLogic.update(user)
} }
@PutMapping("{id}/password", consumes = [MediaType.TEXT_PLAIN_VALUE]) @PutMapping("{id}/password", consumes = [MediaType.TEXT_PLAIN_VALUE])
@PreAuthorizeEditUsers @PreAuthorizeEditUsers
fun updatePassword(@PathVariable id: Long, @RequestBody password: String) = fun updatePassword(@PathVariable id: Long, @RequestBody password: String) =
noContent { noContent {
userService.updatePassword(id, password) userLogic.updatePassword(id, password)
} }
@PutMapping("{userId}/permissions/{permission}") @PutMapping("{userId}/permissions/{permission}")
@ -60,7 +59,7 @@ class UserController(private val userService: UserService) {
@PathVariable userId: Long, @PathVariable userId: Long,
@PathVariable permission: Permission @PathVariable permission: Permission
) = noContent { ) = noContent {
userService.addPermission(userId, permission) userLogic.addPermission(userId, permission)
} }
@DeleteMapping("{userId}/permissions/{permission}") @DeleteMapping("{userId}/permissions/{permission}")
@ -69,37 +68,37 @@ class UserController(private val userService: UserService) {
@PathVariable userId: Long, @PathVariable userId: Long,
@PathVariable permission: Permission @PathVariable permission: Permission
) = noContent { ) = noContent {
userService.removePermission(userId, permission) userLogic.removePermission(userId, permission)
} }
@DeleteMapping("{id}") @DeleteMapping("{id}")
@PreAuthorizeEditUsers @PreAuthorizeEditUsers
fun deleteById(@PathVariable id: Long) = fun deleteById(@PathVariable id: Long) =
userService.deleteById(id) userLogic.deleteById(id)
} }
@RestController @RestController
@RequestMapping(GROUP_CONTROLLER_PATH) @RequestMapping(GROUP_CONTROLLER_PATH)
@Profile("!emergency") @Profile("!emergency")
class GroupsController( class GroupsController(
private val groupService: GroupService, private val groupLogic: GroupLogic,
private val userService: UserService private val userLogic: UserLogic
) { ) {
@GetMapping @GetMapping
@PreAuthorize("hasAnyAuthority('VIEW_RECIPES', 'VIEW_USERS')") @PreAuthorize("hasAnyAuthority('VIEW_RECIPES', 'VIEW_USERS')")
fun getAll() = fun getAll() =
ok(groupService.getAllForOutput()) ok(groupLogic.getAllForOutput())
@GetMapping("{id}") @GetMapping("{id}")
@PreAuthorizeViewUsers @PreAuthorizeViewUsers
fun getById(@PathVariable id: Long) = fun getById(@PathVariable id: Long) =
ok(groupService.getByIdForOutput(id)) ok(groupLogic.getByIdForOutput(id))
@GetMapping("{id}/users") @GetMapping("{id}/users")
@PreAuthorizeViewUsers @PreAuthorizeViewUsers
fun getUsersForGroup(@PathVariable id: Long) = fun getUsersForGroup(@PathVariable id: Long) =
ok(with(userService) { ok(with(userLogic) {
groupService.getUsersForGroup(id) groupLogic.getUsersForGroup(id)
.map { it.toOutput() } .map { it.toOutput() }
}) })
@ -107,27 +106,27 @@ class GroupsController(
@PreAuthorizeViewUsers @PreAuthorizeViewUsers
fun setDefaultGroup(@PathVariable groupId: Long, response: HttpServletResponse) = fun setDefaultGroup(@PathVariable groupId: Long, response: HttpServletResponse) =
noContent { noContent {
groupService.setResponseDefaultGroup(groupId, response) groupLogic.setResponseDefaultGroup(groupId, response)
} }
@GetMapping("default") @GetMapping("default")
@PreAuthorizeViewUsers @PreAuthorizeViewUsers
fun getRequestDefaultGroup(request: HttpServletRequest) = fun getRequestDefaultGroup(request: HttpServletRequest) =
ok(with(groupService) { ok(with(groupLogic) {
getRequestDefaultGroup(request).toOutput() getRequestDefaultGroup(request).toOutput()
}) })
@GetMapping("currentuser") @GetMapping("currentuser")
fun getCurrentGroupUser(request: HttpServletRequest) = fun getCurrentGroupUser(request: HttpServletRequest) =
ok(with(groupService.getRequestDefaultGroup(request)) { ok(with(groupLogic.getRequestDefaultGroup(request)) {
userService.getDefaultGroupUser(this).toOutputDto() userLogic.getDefaultGroupUser(this).toOutputDto()
}) })
@PostMapping @PostMapping
@PreAuthorizeEditUsers @PreAuthorizeEditUsers
fun save(@Valid @RequestBody group: GroupSaveDto) = fun save(@Valid @RequestBody group: GroupSaveDto) =
created<GroupOutputDto>(GROUP_CONTROLLER_PATH) { created<GroupOutputDto>(GROUP_CONTROLLER_PATH) {
with(groupService) { with(groupLogic) {
save(group).toOutput() save(group).toOutput()
} }
} }
@ -136,25 +135,25 @@ class GroupsController(
@PreAuthorizeEditUsers @PreAuthorizeEditUsers
fun update(@Valid @RequestBody group: GroupUpdateDto) = fun update(@Valid @RequestBody group: GroupUpdateDto) =
noContent { noContent {
groupService.update(group) groupLogic.update(group)
} }
@DeleteMapping("{id}") @DeleteMapping("{id}")
@PreAuthorizeEditUsers @PreAuthorizeEditUsers
fun deleteById(@PathVariable id: Long) = fun deleteById(@PathVariable id: Long) =
noContent { noContent {
groupService.deleteById(id) groupLogic.deleteById(id)
} }
} }
@RestController @RestController
@RequestMapping("api") @RequestMapping("api")
@Profile("!emergency") @Profile("!emergency")
class LogoutController(private val userService: UserService) { class LogoutController(private val userLogic: UserLogic) {
@GetMapping("logout") @GetMapping("logout")
@PreAuthorize("isFullyAuthenticated()") @PreAuthorize("isFullyAuthenticated()")
fun logout(request: HttpServletRequest) = fun logout(request: HttpServletRequest) =
ok { 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.Company
import dev.fyloz.colorrecipesexplorer.model.CompanySaveDto import dev.fyloz.colorrecipesexplorer.model.CompanySaveDto
import dev.fyloz.colorrecipesexplorer.model.CompanyUpdateDto import dev.fyloz.colorrecipesexplorer.model.CompanyUpdateDto
import dev.fyloz.colorrecipesexplorer.service.CompanyService
import org.springframework.context.annotation.Profile import org.springframework.context.annotation.Profile
import org.springframework.security.access.prepost.PreAuthorize import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
@ -16,33 +15,33 @@ private const val COMPANY_CONTROLLER_PATH = "api/company"
@RequestMapping(COMPANY_CONTROLLER_PATH) @RequestMapping(COMPANY_CONTROLLER_PATH)
@Profile("!emergency") @Profile("!emergency")
@PreAuthorizeViewCatalog @PreAuthorizeViewCatalog
class CompanyController(private val companyService: CompanyService) { class CompanyController(private val companyLogic: dev.fyloz.colorrecipesexplorer.logic.CompanyLogic) {
@GetMapping @GetMapping
fun getAll() = fun getAll() =
ok(companyService.getAllForOutput()) ok(companyLogic.getAllForOutput())
@GetMapping("{id}") @GetMapping("{id}")
fun getById(@PathVariable id: Long) = fun getById(@PathVariable id: Long) =
ok(companyService.getByIdForOutput(id)) ok(companyLogic.getByIdForOutput(id))
@PostMapping @PostMapping
@PreAuthorize("hasAuthority('EDIT_COMPANIES')") @PreAuthorize("hasAuthority('EDIT_COMPANIES')")
fun save(@Valid @RequestBody company: CompanySaveDto) = fun save(@Valid @RequestBody company: CompanySaveDto) =
created<Company>(COMPANY_CONTROLLER_PATH) { created<Company>(COMPANY_CONTROLLER_PATH) {
companyService.save(company) companyLogic.save(company)
} }
@PutMapping @PutMapping
@PreAuthorize("hasAuthority('EDIT_COMPANIES')") @PreAuthorize("hasAuthority('EDIT_COMPANIES')")
fun update(@Valid @RequestBody company: CompanyUpdateDto) = fun update(@Valid @RequestBody company: CompanyUpdateDto) =
noContent { noContent {
companyService.update(company) companyLogic.update(company)
} }
@DeleteMapping("{id}") @DeleteMapping("{id}")
@PreAuthorize("hasAuthority('EDIT_COMPANIES')") @PreAuthorize("hasAuthority('EDIT_COMPANIES')")
fun deleteById(@PathVariable id: Long) = fun deleteById(@PathVariable id: Long) =
noContent { noContent {
companyService.deleteById(id) companyLogic.deleteById(id)
} }
} }

View File

@ -1,37 +1,35 @@
package dev.fyloz.colorrecipesexplorer.rest package dev.fyloz.colorrecipesexplorer.rest
import dev.fyloz.colorrecipesexplorer.logic.config.ConfigurationLogic
import dev.fyloz.colorrecipesexplorer.model.ConfigurationBase import dev.fyloz.colorrecipesexplorer.model.ConfigurationBase
import dev.fyloz.colorrecipesexplorer.model.ConfigurationDto 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.Permission
import dev.fyloz.colorrecipesexplorer.model.account.toAuthority import dev.fyloz.colorrecipesexplorer.model.account.toAuthority
import dev.fyloz.colorrecipesexplorer.restartApplication import dev.fyloz.colorrecipesexplorer.restartApplication
import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService
import org.springframework.http.MediaType import org.springframework.http.MediaType
import org.springframework.security.access.prepost.PreAuthorize import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.security.core.Authentication import org.springframework.security.core.Authentication
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile import org.springframework.web.multipart.MultipartFile
import javax.validation.constraints.NotBlank
@RestController @RestController
@RequestMapping("api/config") @RequestMapping("api/config")
class ConfigurationController(val configurationService: ConfigurationService) { class ConfigurationController(val configurationLogic: ConfigurationLogic) {
@GetMapping @GetMapping
fun getAll(@RequestParam(required = false) keys: String?, authentication: Authentication?) = fun getAll(@RequestParam(required = false) keys: String?, authentication: Authentication?) =
ok(with(configurationService) { ok(with(configurationLogic) {
if (keys != null) getAll(keys) else getAll() if (keys != null) getAll(keys) else getAll()
}.filter { authentication.hasAuthority(it) }) }.filter { authentication.hasAuthority(it) })
@GetMapping("{key}") @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() if (authentication.hasAuthority(this)) ok(this) else forbidden()
} }
@PutMapping @PutMapping
@PreAuthorize("hasAuthority('ADMIN')") @PreAuthorize("hasAuthority('ADMIN')")
fun set(@RequestBody configurations: List<ConfigurationDto>) = noContent { fun set(@RequestBody configurations: List<ConfigurationDto>) = noContent {
configurationService.set(configurations) configurationLogic.set(configurations)
} }
@PostMapping("restart") @PostMapping("restart")
@ -44,24 +42,24 @@ class ConfigurationController(val configurationService: ConfigurationService) {
@GetMapping("icon") @GetMapping("icon")
fun getIcon() = fun getIcon() =
okFile(configurationService.getConfiguredIcon(), MediaType.IMAGE_PNG_VALUE) okFile(configurationLogic.getConfiguredIcon(), MediaType.IMAGE_PNG_VALUE)
@PutMapping("icon") @PutMapping("icon")
@PreAuthorize("hasAuthority('ADMIN')") @PreAuthorize("hasAuthority('ADMIN')")
fun setIcon(@RequestParam icon: MultipartFile) = noContent { fun setIcon(@RequestParam icon: MultipartFile) = noContent {
configurationService.setConfiguredIcon(icon) configurationLogic.setConfiguredIcon(icon)
} }
// Logo // Logo
@GetMapping("logo") @GetMapping("logo")
fun getLogo() = fun getLogo() =
okFile(configurationService.getConfiguredLogo(), MediaType.IMAGE_PNG_VALUE) okFile(configurationLogic.getConfiguredLogo(), MediaType.IMAGE_PNG_VALUE)
@PutMapping("logo") @PutMapping("logo")
@PreAuthorize("hasAuthority('ADMIN')") @PreAuthorize("hasAuthority('ADMIN')")
fun setLogo(@RequestParam logo: MultipartFile) = noContent { fun setLogo(@RequestParam logo: MultipartFile) = noContent {
configurationService.setConfiguredLogo(logo) configurationLogic.setConfiguredLogo(logo)
} }
} }

View File

@ -1,8 +1,8 @@
package dev.fyloz.colorrecipesexplorer.rest 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.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.MediaType
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.security.access.prepost.PreAuthorize import org.springframework.security.access.prepost.PreAuthorize
@ -15,14 +15,14 @@ const val FILE_CONTROLLER_PATH = "/api/file"
@RestController @RestController
@RequestMapping(FILE_CONTROLLER_PATH) @RequestMapping(FILE_CONTROLLER_PATH)
class FileController( class FileController(
private val fileService: WriteableFileService, private val fileLogic: WriteableFileLogic,
private val configService: ConfigurationService private val configurationLogic: ConfigurationLogic
) { ) {
@GetMapping(produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE]) @GetMapping(produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE])
fun upload( fun upload(
@RequestParam path: String, @RequestParam path: String,
@RequestParam(required = false) mediaType: String? @RequestParam(required = false) mediaType: String?
) = okFile(fileService.read(path), mediaType) ) = okFile(fileLogic.read(path), mediaType)
@PutMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]) @PutMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
@PreAuthorize("hasAnyAuthority('WRITE_FILE')") @PreAuthorize("hasAnyAuthority('WRITE_FILE')")
@ -31,7 +31,7 @@ class FileController(
@RequestParam path: String, @RequestParam path: String,
@RequestParam(required = false) overwrite: Boolean = false @RequestParam(required = false) overwrite: Boolean = false
): ResponseEntity<Void> { ): ResponseEntity<Void> {
fileService.write(file, path, overwrite) fileLogic.write(file, path, overwrite)
return created(path) return created(path)
} }
@ -39,11 +39,11 @@ class FileController(
@PreAuthorize("hasAnyAuthority('WRITE_FILE')") @PreAuthorize("hasAnyAuthority('WRITE_FILE')")
fun delete(@RequestParam path: String): ResponseEntity<Void> = fun delete(@RequestParam path: String): ResponseEntity<Void> =
noContent { noContent {
fileService.delete(path) fileLogic.delete(path)
} }
private fun created(path: String): ResponseEntity<Void> = private fun created(path: String): ResponseEntity<Void> =
ResponseEntity 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() .build()
} }

View File

@ -1,10 +1,9 @@
package dev.fyloz.colorrecipesexplorer.rest package dev.fyloz.colorrecipesexplorer.rest
import dev.fyloz.colorrecipesexplorer.logic.InventoryLogic
import dev.fyloz.colorrecipesexplorer.model.MaterialQuantityDto import dev.fyloz.colorrecipesexplorer.model.MaterialQuantityDto
import dev.fyloz.colorrecipesexplorer.model.MixDeductDto import dev.fyloz.colorrecipesexplorer.model.MixDeductDto
import dev.fyloz.colorrecipesexplorer.service.InventoryService
import org.springframework.context.annotation.Profile import org.springframework.context.annotation.Profile
import org.springframework.http.ResponseEntity
import org.springframework.security.access.prepost.PreAuthorize import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.PutMapping import org.springframework.web.bind.annotation.PutMapping
import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestBody
@ -17,20 +16,20 @@ private const val INVENTORY_CONTROLLER_PATH = "api/inventory"
@RequestMapping(INVENTORY_CONTROLLER_PATH) @RequestMapping(INVENTORY_CONTROLLER_PATH)
@Profile("!emergency") @Profile("!emergency")
class InventoryController( class InventoryController(
private val inventoryService: InventoryService private val inventoryLogic: InventoryLogic
) { ) {
@PutMapping("add") @PutMapping("add")
@PreAuthorize("hasAuthority('ADD_TO_INVENTORY')") @PreAuthorize("hasAuthority('ADD_TO_INVENTORY')")
fun add(@RequestBody quantities: Collection<MaterialQuantityDto>) = fun add(@RequestBody quantities: Collection<MaterialQuantityDto>) =
ok(inventoryService.add(quantities)) ok(inventoryLogic.add(quantities))
@PutMapping("deduct") @PutMapping("deduct")
@PreAuthorize("hasAuthority('DEDUCT_FROM_INVENTORY')") @PreAuthorize("hasAuthority('DEDUCT_FROM_INVENTORY')")
fun deduct(@RequestBody quantities: Collection<MaterialQuantityDto>) = fun deduct(@RequestBody quantities: Collection<MaterialQuantityDto>) =
ok(inventoryService.deduct(quantities)) ok(inventoryLogic.deduct(quantities))
@PutMapping("deduct/mix") @PutMapping("deduct/mix")
@PreAuthorize("hasAuthority('DEDUCT_FROM_INVENTORY')") @PreAuthorize("hasAuthority('DEDUCT_FROM_INVENTORY')")
fun deduct(@RequestBody mixRatio: MixDeductDto) = fun deduct(@RequestBody mixRatio: MixDeductDto) =
ok(inventoryService.deductMix(mixRatio)) ok(inventoryLogic.deductMix(mixRatio))
} }

View File

@ -1,16 +1,13 @@
package dev.fyloz.colorrecipesexplorer.rest package dev.fyloz.colorrecipesexplorer.rest
import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeViewCatalog 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.model.*
import dev.fyloz.colorrecipesexplorer.service.MaterialService
import org.springframework.context.annotation.Profile import org.springframework.context.annotation.Profile
import org.springframework.http.MediaType import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.security.access.prepost.PreAuthorize import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile import org.springframework.web.multipart.MultipartFile
import java.net.URI
import javax.validation.Valid import javax.validation.Valid
private const val MATERIAL_CONTROLLER_PATH = "api/material" private const val MATERIAL_CONTROLLER_PATH = "api/material"
@ -20,25 +17,25 @@ private const val MATERIAL_CONTROLLER_PATH = "api/material"
@Profile("!emergency") @Profile("!emergency")
@PreAuthorizeViewCatalog @PreAuthorizeViewCatalog
class MaterialController( class MaterialController(
private val materialService: MaterialService private val materialLogic: MaterialLogic
) { ) {
@GetMapping @GetMapping
fun getAll() = fun getAll() =
ok(materialService.getAllForOutput()) ok(materialLogic.getAllForOutput())
@GetMapping("notmixtype") @GetMapping("notmixtype")
fun getAllNotMixType() = fun getAllNotMixType() =
ok(materialService.getAllNotMixType()) ok(materialLogic.getAllNotMixType())
@GetMapping("{id}") @GetMapping("{id}")
fun getById(@PathVariable id: Long) = fun getById(@PathVariable id: Long) =
ok(materialService.getByIdForOutput(id)) ok(materialLogic.getByIdForOutput(id))
@PostMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]) @PostMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
@PreAuthorize("hasAuthority('EDIT_MATERIALS')") @PreAuthorize("hasAuthority('EDIT_MATERIALS')")
fun save(@Valid material: MaterialSaveDto, simdutFile: MultipartFile?) = fun save(@Valid material: MaterialSaveDto, simdutFile: MultipartFile?) =
created<MaterialOutputDto>(MATERIAL_CONTROLLER_PATH) { created<MaterialOutputDto>(MATERIAL_CONTROLLER_PATH) {
with(materialService) { with(materialLogic) {
save( save(
materialSaveDto( materialSaveDto(
name = material.name, name = material.name,
@ -54,7 +51,7 @@ class MaterialController(
@PreAuthorize("hasAuthority('EDIT_MATERIALS')") @PreAuthorize("hasAuthority('EDIT_MATERIALS')")
fun update(@Valid material: MaterialUpdateDto, simdutFile: MultipartFile?) = fun update(@Valid material: MaterialUpdateDto, simdutFile: MultipartFile?) =
noContent { noContent {
materialService.update( materialLogic.update(
materialUpdateDto( materialUpdateDto(
id = material.id, id = material.id,
name = material.name, name = material.name,
@ -69,15 +66,15 @@ class MaterialController(
@PreAuthorize("hasAuthority('EDIT_MATERIALS')") @PreAuthorize("hasAuthority('EDIT_MATERIALS')")
fun deleteById(@PathVariable id: Long) = fun deleteById(@PathVariable id: Long) =
noContent { noContent {
materialService.deleteById(id) materialLogic.deleteById(id)
} }
@GetMapping("mix/create/{recipeId}") @GetMapping("mix/create/{recipeId}")
fun getAllForMixCreation(@PathVariable recipeId: Long) = fun getAllForMixCreation(@PathVariable recipeId: Long) =
ok(materialService.getAllForMixCreation(recipeId)) ok(materialLogic.getAllForMixCreation(recipeId))
@GetMapping("mix/update/{mixId}") @GetMapping("mix/update/{mixId}")
fun getAllForMixUpdate(@PathVariable mixId: Long) = fun getAllForMixUpdate(@PathVariable mixId: Long) =
ok(materialService.getAllForMixUpdate(mixId)) ok(materialLogic.getAllForMixUpdate(mixId))
} }

View File

@ -1,10 +1,10 @@
package dev.fyloz.colorrecipesexplorer.rest package dev.fyloz.colorrecipesexplorer.rest
import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeViewCatalog import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeViewCatalog
import dev.fyloz.colorrecipesexplorer.logic.MaterialTypeLogic
import dev.fyloz.colorrecipesexplorer.model.MaterialType import dev.fyloz.colorrecipesexplorer.model.MaterialType
import dev.fyloz.colorrecipesexplorer.model.MaterialTypeSaveDto import dev.fyloz.colorrecipesexplorer.model.MaterialTypeSaveDto
import dev.fyloz.colorrecipesexplorer.model.MaterialTypeUpdateDto import dev.fyloz.colorrecipesexplorer.model.MaterialTypeUpdateDto
import dev.fyloz.colorrecipesexplorer.service.MaterialTypeService
import org.springframework.context.annotation.Profile import org.springframework.context.annotation.Profile
import org.springframework.security.access.prepost.PreAuthorize import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
@ -16,34 +16,34 @@ private const val MATERIAL_TYPE_CONTROLLER_PATH = "api/materialtype"
@RequestMapping(MATERIAL_TYPE_CONTROLLER_PATH) @RequestMapping(MATERIAL_TYPE_CONTROLLER_PATH)
@Profile("!emergency") @Profile("!emergency")
@PreAuthorizeViewCatalog @PreAuthorizeViewCatalog
class MaterialTypeController(private val materialTypeService: MaterialTypeService) { class MaterialTypeController(private val materialTypeLogic: MaterialTypeLogic) {
@GetMapping @GetMapping
fun getAll() = fun getAll() =
ok(materialTypeService.getAllForOutput()) ok(materialTypeLogic.getAllForOutput())
@GetMapping("{id}") @GetMapping("{id}")
fun getById(@PathVariable id: Long) = fun getById(@PathVariable id: Long) =
ok(materialTypeService.getByIdForOutput(id)) ok(materialTypeLogic.getByIdForOutput(id))
@PostMapping @PostMapping
@PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')") @PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')")
fun save(@Valid @RequestBody materialType: MaterialTypeSaveDto) = fun save(@Valid @RequestBody materialType: MaterialTypeSaveDto) =
created<MaterialType>(MATERIAL_TYPE_CONTROLLER_PATH) { created<MaterialType>(MATERIAL_TYPE_CONTROLLER_PATH) {
materialTypeService.save(materialType) materialTypeLogic.save(materialType)
} }
@PutMapping @PutMapping
@PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')") @PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')")
fun update(@Valid @RequestBody materialType: MaterialTypeUpdateDto) = fun update(@Valid @RequestBody materialType: MaterialTypeUpdateDto) =
noContent { noContent {
materialTypeService.update(materialType) materialTypeLogic.update(materialType)
} }
@DeleteMapping("{id}") @DeleteMapping("{id}")
@PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')") @PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')")
fun deleteById(@PathVariable id: Long) = fun deleteById(@PathVariable id: Long) =
noContent { 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.PreAuthorizeEditRecipes
import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeViewRecipes 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.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.context.annotation.Profile
import org.springframework.http.MediaType import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
@ -23,27 +23,27 @@ private const val MIX_CONTROLLER_PATH = "api/recipe/mix"
@Profile("!emergency") @Profile("!emergency")
@PreAuthorizeViewRecipes @PreAuthorizeViewRecipes
class RecipeController( class RecipeController(
private val recipeService: RecipeService, private val recipeLogic: RecipeLogic,
private val recipeImageService: RecipeImageService private val recipeImageLogic: RecipeImageLogic
) { ) {
@GetMapping @GetMapping
fun getAll(@RequestParam(required = false) name: String?) = fun getAll(@RequestParam(required = false) name: String?) =
if (name == null) if (name == null)
ok(recipeService.getAllForOutput()) ok(recipeLogic.getAllForOutput())
else else
ok(with(recipeService) { ok(with(recipeLogic) {
getAllByName(name).map { it.toOutput() } getAllByName(name).map { it.toOutput() }
}) })
@GetMapping("{id}") @GetMapping("{id}")
fun getById(@PathVariable id: Long) = fun getById(@PathVariable id: Long) =
ok(recipeService.getByIdForOutput(id)) ok(recipeLogic.getByIdForOutput(id))
@PostMapping @PostMapping
@PreAuthorizeEditRecipes @PreAuthorizeEditRecipes
fun save(@Valid @RequestBody recipe: RecipeSaveDto) = fun save(@Valid @RequestBody recipe: RecipeSaveDto) =
created<RecipeOutputDto>(RECIPE_CONTROLLER_PATH) { created<RecipeOutputDto>(RECIPE_CONTROLLER_PATH) {
with(recipeService) { with(recipeLogic) {
save(recipe).toOutput() save(recipe).toOutput()
} }
} }
@ -52,27 +52,27 @@ class RecipeController(
@PreAuthorizeEditRecipes @PreAuthorizeEditRecipes
fun update(@Valid @RequestBody recipe: RecipeUpdateDto) = fun update(@Valid @RequestBody recipe: RecipeUpdateDto) =
noContent { noContent {
recipeService.update(recipe) recipeLogic.update(recipe)
} }
@PutMapping("public") @PutMapping("public")
@PreAuthorize("hasAuthority('EDIT_RECIPES_PUBLIC_DATA')") @PreAuthorize("hasAuthority('EDIT_RECIPES_PUBLIC_DATA')")
fun updatePublicData(@Valid @RequestBody publicDataDto: RecipePublicDataDto) = fun updatePublicData(@Valid @RequestBody publicDataDto: RecipePublicDataDto) =
noContent { noContent {
recipeService.updatePublicData(publicDataDto) recipeLogic.updatePublicData(publicDataDto)
} }
@DeleteMapping("{id}") @DeleteMapping("{id}")
@PreAuthorizeEditRecipes @PreAuthorizeEditRecipes
fun deleteById(@PathVariable id: Long) = fun deleteById(@PathVariable id: Long) =
noContent { noContent {
recipeService.deleteById(id) recipeLogic.deleteById(id)
} }
@PutMapping("{recipeId}/image", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]) @PutMapping("{recipeId}/image", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
@PreAuthorizeEditRecipes @PreAuthorizeEditRecipes
fun downloadImage(@PathVariable recipeId: Long, image: MultipartFile): ResponseEntity<RecipeOutputDto> { fun downloadImage(@PathVariable recipeId: Long, image: MultipartFile): ResponseEntity<RecipeOutputDto> {
recipeImageService.download(image, recipeService.getById(recipeId)) recipeImageLogic.download(image, recipeLogic.getById(recipeId))
return getById(recipeId) return getById(recipeId)
} }
@ -80,7 +80,7 @@ class RecipeController(
@PreAuthorizeEditRecipes @PreAuthorizeEditRecipes
fun deleteImage(@PathVariable recipeId: Long, @PathVariable name: String) = fun deleteImage(@PathVariable recipeId: Long, @PathVariable name: String) =
noContent { noContent {
recipeImageService.delete(recipeService.getById(recipeId), name) recipeImageLogic.delete(recipeLogic.getById(recipeId), name)
} }
} }
@ -88,29 +88,29 @@ class RecipeController(
@RequestMapping(MIX_CONTROLLER_PATH) @RequestMapping(MIX_CONTROLLER_PATH)
@Profile("!emergency") @Profile("!emergency")
@PreAuthorizeViewRecipes @PreAuthorizeViewRecipes
class MixController(private val mixService: MixService) { class MixController(private val mixLogic: MixLogic) {
@GetMapping("{id}") @GetMapping("{id}")
fun getById(@PathVariable id: Long) = fun getById(@PathVariable id: Long) =
ok(mixService.getByIdForOutput(id)) ok(mixLogic.getByIdForOutput(id))
@PostMapping @PostMapping
@PreAuthorizeEditRecipes @PreAuthorizeEditRecipes
fun save(@Valid @RequestBody mix: MixSaveDto) = fun save(@Valid @RequestBody mix: MixSaveDto) =
created<Mix>(MIX_CONTROLLER_PATH) { created<Mix>(MIX_CONTROLLER_PATH) {
mixService.save(mix) mixLogic.save(mix)
} }
@PutMapping @PutMapping
@PreAuthorizeEditRecipes @PreAuthorizeEditRecipes
fun update(@Valid @RequestBody mix: MixUpdateDto) = fun update(@Valid @RequestBody mix: MixUpdateDto) =
noContent { noContent {
mixService.update(mix) mixLogic.update(mix)
} }
@DeleteMapping("{id}") @DeleteMapping("{id}")
@PreAuthorizeEditRecipes @PreAuthorizeEditRecipes
fun deleteById(@PathVariable id: Long) = fun deleteById(@PathVariable id: Long) =
noContent { noContent {
mixService.deleteById(id) mixLogic.deleteById(id)
} }
} }

View File

@ -1,9 +1,9 @@
package dev.fyloz.colorrecipesexplorer.rest package dev.fyloz.colorrecipesexplorer.rest
import dev.fyloz.colorrecipesexplorer.logic.TouchUpKitLogic
import dev.fyloz.colorrecipesexplorer.model.touchupkit.TouchUpKitOutputDto import dev.fyloz.colorrecipesexplorer.model.touchupkit.TouchUpKitOutputDto
import dev.fyloz.colorrecipesexplorer.model.touchupkit.TouchUpKitSaveDto import dev.fyloz.colorrecipesexplorer.model.touchupkit.TouchUpKitSaveDto
import dev.fyloz.colorrecipesexplorer.model.touchupkit.TouchUpKitUpdateDto import dev.fyloz.colorrecipesexplorer.model.touchupkit.TouchUpKitUpdateDto
import dev.fyloz.colorrecipesexplorer.service.TouchUpKitService
import org.springframework.context.annotation.Profile import org.springframework.context.annotation.Profile
import org.springframework.core.io.Resource import org.springframework.core.io.Resource
import org.springframework.http.MediaType import org.springframework.http.MediaType
@ -19,21 +19,21 @@ const val TOUCH_UP_KIT_CONTROLLER_PATH = "/api/touchupkit"
@Profile("!emergency") @Profile("!emergency")
@PreAuthorize("hasAuthority('VIEW_TOUCH_UP_KITS')") @PreAuthorize("hasAuthority('VIEW_TOUCH_UP_KITS')")
class TouchUpKitController( class TouchUpKitController(
private val touchUpKitService: TouchUpKitService private val touchUpKitLogic: TouchUpKitLogic
) { ) {
@GetMapping @GetMapping
fun getAll() = fun getAll() =
ok(touchUpKitService.getAllForOutput()) ok(touchUpKitLogic.getAllForOutput())
@GetMapping("{id}") @GetMapping("{id}")
fun getById(@PathVariable id: Long) = fun getById(@PathVariable id: Long) =
ok(touchUpKitService.getByIdForOutput(id)) ok(touchUpKitLogic.getByIdForOutput(id))
@PostMapping @PostMapping
@PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')") @PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')")
fun save(@Valid @RequestBody touchUpKit: TouchUpKitSaveDto) = fun save(@Valid @RequestBody touchUpKit: TouchUpKitSaveDto) =
created<TouchUpKitOutputDto>(TOUCH_UP_KIT_CONTROLLER_PATH) { created<TouchUpKitOutputDto>(TOUCH_UP_KIT_CONTROLLER_PATH) {
with(touchUpKitService) { with(touchUpKitLogic) {
save(touchUpKit).toOutput() save(touchUpKit).toOutput()
} }
} }
@ -41,24 +41,24 @@ class TouchUpKitController(
@PutMapping @PutMapping
@PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')") @PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')")
fun update(@Valid @RequestBody touchUpKit: TouchUpKitUpdateDto) = noContent { fun update(@Valid @RequestBody touchUpKit: TouchUpKitUpdateDto) = noContent {
touchUpKitService.update(touchUpKit) touchUpKitLogic.update(touchUpKit)
} }
@PutMapping("{id}/complete") @PutMapping("{id}/complete")
@PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')") @PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')")
fun complete(@PathVariable id: Long) = noContent { fun complete(@PathVariable id: Long) = noContent {
touchUpKitService.complete(id) touchUpKitLogic.complete(id)
} }
@DeleteMapping("{id}") @DeleteMapping("{id}")
@PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')") @PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')")
fun deleteById(@PathVariable id: Long) = noContent { fun deleteById(@PathVariable id: Long) = noContent {
touchUpKitService.deleteById(id) touchUpKitLogic.deleteById(id)
} }
@GetMapping("pdf") @GetMapping("pdf")
fun getJobPdf(@RequestParam project: String): ResponseEntity<Resource> { fun getJobPdf(@RequestParam project: String): ResponseEntity<Resource> {
with(touchUpKitService.generateJobPdfResource(project)) { with(touchUpKitLogic.generateJobPdfResource(project)) {
return ResponseEntity.ok() return ResponseEntity.ok()
.header("Content-Disposition", "filename=TouchUpKit_$project.pdf") .header("Content-Disposition", "filename=TouchUpKit_$project.pdf")
.contentLength(this.contentLength()) .contentLength(this.contentLength())

View File

@ -1,4 +1,4 @@
package dev.fyloz.colorrecipesexplorer.service package dev.fyloz.colorrecipesexplorer.logic
import com.nhaarman.mockitokotlin2.* import com.nhaarman.mockitokotlin2.*
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
@ -16,11 +16,11 @@ import java.util.*
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertTrue 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, *>> { abstract class AbstractServiceTest<E, S : Service<E, *>, R : JpaRepository<E, *>> {
protected abstract val repository: R protected abstract val repository: R
protected abstract val service: S protected abstract val logic: S
protected abstract val entity: E protected abstract val entity: E
protected abstract val anotherEntity: E protected abstract val anotherEntity: E
@ -33,7 +33,7 @@ abstract class AbstractServiceTest<E, S : Service<E, *>, R : JpaRepository<E, *>
@AfterEach @AfterEach
open fun afterEach() { open fun afterEach() {
reset(repository, service) reset(repository, logic)
} }
// getAll() // getAll()
@ -42,7 +42,7 @@ abstract class AbstractServiceTest<E, S : Service<E, *>, R : JpaRepository<E, *>
open fun `getAll() returns all available entities`() { open fun `getAll() returns all available entities`() {
whenever(repository.findAll()).doReturn(entityList) whenever(repository.findAll()).doReturn(entityList)
val found = service.getAll() val found = logic.getAll()
assertEquals(entityList, found) 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`() { open fun `getAll() returns empty list when there is no entities`() {
whenever(repository.findAll()).doReturn(listOf()) whenever(repository.findAll()).doReturn(listOf())
val found = service.getAll() val found = logic.getAll()
assertTrue { found.isEmpty() } 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`() { open fun `save() saves in the repository and returns the saved value`() {
whenever(repository.save(entity)).doReturn(entity) whenever(repository.save(entity)).doReturn(entity)
val found = service.save(entity) val found = logic.save(entity)
verify(repository).save(entity) verify(repository).save(entity)
assertEquals(entity, found) 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`() { open fun `update() saves in the repository and returns the updated value`() {
whenever(repository.save(entity)).doReturn(entity) whenever(repository.save(entity)).doReturn(entity)
val found = service.update(entity) val found = logic.update(entity)
verify(repository).save(entity) verify(repository).save(entity)
assertEquals(entity, found) assertEquals(entity, found)
@ -84,7 +84,7 @@ abstract class AbstractServiceTest<E, S : Service<E, *>, R : JpaRepository<E, *>
@Test @Test
open fun `delete() deletes in the repository`() { open fun `delete() deletes in the repository`() {
service.delete(entity) logic.delete(entity)
verify(repository).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`() { open fun `existsById() returns true when an entity with the given id exists in the repository`() {
whenever(repository.existsById(entity.id!!)).doReturn(true) whenever(repository.existsById(entity.id!!)).doReturn(true)
val found = service.existsById(entity.id!!) val found = logic.existsById(entity.id!!)
assertTrue(found) 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`() { open fun `existsById() returns false when no entity with the given id exists in the repository`() {
whenever(repository.existsById(entity.id!!)).doReturn(false) whenever(repository.existsById(entity.id!!)).doReturn(false)
val found = service.existsById(entity.id!!) val found = logic.existsById(entity.id!!)
assertFalse(found) 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`() { open fun `getById() returns the entity with the given id from the repository`() {
whenever(repository.findById(entity.id!!)).doReturn(Optional.of(entity)) whenever(repository.findById(entity.id!!)).doReturn(Optional.of(entity))
val found = service.getById(entity.id!!) val found = logic.getById(entity.id!!)
assertEquals(entity, found) 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`() { open fun `getById() throws NotFoundException when no entity with the given id exists in the repository`() {
whenever(repository.findById(entity.id!!)).doReturn(Optional.empty()) whenever(repository.findById(entity.id!!)).doReturn(Optional.empty())
assertThrows<NotFoundException> { service.getById(entity.id!!) } assertThrows<NotFoundException> { logic.getById(entity.id!!) }
.assertErrorCode() .assertErrorCode()
} }
@ -136,9 +136,9 @@ abstract class AbstractModelServiceTest<E : Model, S : ModelService<E, *>, R : J
@Test @Test
open fun `save() throws AlreadyExistsException when an entity with the given id exists in the repository`() { 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() .assertErrorCode()
} }
@ -147,10 +147,10 @@ abstract class AbstractModelServiceTest<E : Model, S : ModelService<E, *>, R : J
@Test @Test
override fun `update() saves in the repository and returns the updated value`() { override fun `update() saves in the repository and returns the updated value`() {
whenever(repository.save(entity)).doReturn(entity) whenever(repository.save(entity)).doReturn(entity)
doReturn(true).whenever(service).existsById(entity.id!!) doReturn(true).whenever(logic).existsById(entity.id!!)
doReturn(entity).whenever(service).getById(entity.id!!) doReturn(entity).whenever(logic).getById(entity.id!!)
val found = service.update(entity) val found = logic.update(entity)
verify(repository).save(entity) verify(repository).save(entity)
assertEquals(entity, found) assertEquals(entity, found)
@ -158,9 +158,9 @@ abstract class AbstractModelServiceTest<E : Model, S : ModelService<E, *>, R : J
@Test @Test
open fun `update() throws NotFoundException when no entity with the given id exists in the repository`() { 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() .assertErrorCode()
} }
@ -168,9 +168,9 @@ abstract class AbstractModelServiceTest<E : Model, S : ModelService<E, *>, R : J
@Test @Test
open fun `deleteById() deletes the entity with the given id in the repository`() { 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) 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`() { open fun `existsByName() returns true when an entity with the given name exists`() {
whenever(repository.existsByName(entity.name)).doReturn(true) whenever(repository.existsByName(entity.name)).doReturn(true)
val found = service.existsByName(entity.name) val found = logic.existsByName(entity.name)
assertTrue(found) 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`() { open fun `existsByName() returns false when no entity with the given name exists`() {
whenever(repository.existsByName(entity.name)).doReturn(false) whenever(repository.existsByName(entity.name)).doReturn(false)
val found = service.existsByName(entity.name) val found = logic.existsByName(entity.name)
assertFalse(found) assertFalse(found)
} }
@ -206,7 +206,7 @@ abstract class AbstractNamedModelServiceTest<E : NamedModel, S : NamedModelServi
open fun `getByName() returns the entity with the given name`() { open fun `getByName() returns the entity with the given name`() {
whenever(repository.findByName(entity.name)).doReturn(entity) whenever(repository.findByName(entity.name)).doReturn(entity)
val found = service.getByName(entity.name) val found = logic.getByName(entity.name)
assertEquals(entity, found) 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`() { open fun `getByName() throws NotFoundException when no entity with the given name exists`() {
whenever(repository.findByName(entity.name)).doReturn(null) whenever(repository.findByName(entity.name)).doReturn(null)
assertThrows<NotFoundException> { service.getByName(entity.name) } assertThrows<NotFoundException> { logic.getByName(entity.name) }
.assertErrorCode("name") .assertErrorCode("name")
} }
@ -223,9 +223,9 @@ abstract class AbstractNamedModelServiceTest<E : NamedModel, S : NamedModelServi
@Test @Test
open fun `save() throws AlreadyExistsException when an entity with the given name exists`() { 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") .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`() { override fun `update() saves in the repository and returns the updated value`() {
whenever(repository.save(entity)).doReturn(entity) whenever(repository.save(entity)).doReturn(entity)
whenever(repository.findByName(entity.name)).doReturn(null) whenever(repository.findByName(entity.name)).doReturn(null)
doReturn(true).whenever(service).existsById(entity.id!!) doReturn(true).whenever(logic).existsById(entity.id!!)
doReturn(entity).whenever(service).getById(entity.id!!) doReturn(entity).whenever(logic).getById(entity.id!!)
val found = service.update(entity) val found = logic.update(entity)
verify(repository).save(entity) verify(repository).save(entity)
assertEquals(entity, found) assertEquals(entity, found)
@ -247,17 +247,17 @@ abstract class AbstractNamedModelServiceTest<E : NamedModel, S : NamedModelServi
@Test @Test
override fun `update() throws NotFoundException when no entity with the given id exists in the repository`() { 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.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 @Test
open fun `update() throws AlreadyExistsException when an entity with the updated name exists`() { open fun `update() throws AlreadyExistsException when an entity with the updated name exists`() {
whenever(repository.findByName(entity.name)).doReturn(entityWithEntityName) 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") .assertErrorCode("name")
} }
} }

View File

@ -1,4 +1,4 @@
package dev.fyloz.colorrecipesexplorer.service package dev.fyloz.colorrecipesexplorer.logic
import com.nhaarman.mockitokotlin2.* import com.nhaarman.mockitokotlin2.*
import dev.fyloz.colorrecipesexplorer.config.security.defaultGroupCookieName 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.model.account.*
import dev.fyloz.colorrecipesexplorer.repository.GroupRepository import dev.fyloz.colorrecipesexplorer.repository.GroupRepository
import dev.fyloz.colorrecipesexplorer.repository.UserRepository 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.junit.jupiter.api.*
import org.springframework.mock.web.MockHttpServletResponse import org.springframework.mock.web.MockHttpServletResponse
import org.springframework.security.core.userdetails.UsernameNotFoundException import org.springframework.security.core.userdetails.UsernameNotFoundException
@ -21,8 +21,8 @@ import kotlin.test.assertNotNull
import kotlin.test.assertTrue import kotlin.test.assertTrue
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class UserServiceTest : class UserLogicTest :
AbstractExternalModelServiceTest<User, UserSaveDto, UserUpdateDto, UserService, UserRepository>() { AbstractExternalModelServiceTest<User, UserSaveDto, UserUpdateDto, UserLogic, UserRepository>() {
private val passwordEncoder = BCryptPasswordEncoder() private val passwordEncoder = BCryptPasswordEncoder()
override val entity: User = user(id = 0L, passwordEncoder = passwordEncoder) 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 entityUpdateDto: UserUpdateDto = spy(userUpdateDto(id = 0L))
override val repository: UserRepository = mock() override val repository: UserRepository = mock()
private val groupService: GroupService = mock() private val groupService: GroupLogic = mock()
override val service: UserService = spy(UserServiceImpl(repository, groupService)) override val logic: UserLogic = spy(DefaultUserLogic(repository, groupService))
private val entitySaveDtoUser = User( private val entitySaveDtoUser = User(
entitySaveDto.id, entitySaveDto.id,
@ -60,7 +60,7 @@ class UserServiceTest :
fun `existsByFirstNameAndLastName() returns true when an user with the given first name and last name exists`() { 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) 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) assertTrue(found)
} }
@ -69,7 +69,7 @@ class UserServiceTest :
fun `existsByFirstNameAndLastName() returns false when no user with the given first name and last name exists`() { 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) 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) assertFalse(found)
} }
@ -81,7 +81,7 @@ class UserServiceTest :
whenever(repository.findById(entityDefaultGroupUser.id)).doReturn(Optional.of(entityDefaultGroupUser)) whenever(repository.findById(entityDefaultGroupUser.id)).doReturn(Optional.of(entityDefaultGroupUser))
assertThrows<NotFoundException> { assertThrows<NotFoundException> {
service.getById( logic.getById(
entityDefaultGroupUser.id, entityDefaultGroupUser.id,
ignoreDefaultGroupUsers = true, ignoreDefaultGroupUsers = true,
ignoreSystemUsers = false ignoreSystemUsers = false
@ -94,7 +94,7 @@ class UserServiceTest :
whenever(repository.findById(entitySystemUser.id)).doReturn(Optional.of(entitySystemUser)) whenever(repository.findById(entitySystemUser.id)).doReturn(Optional.of(entitySystemUser))
assertThrows<NotFoundException> { assertThrows<NotFoundException> {
service.getById( logic.getById(
entitySystemUser.id, entitySystemUser.id,
ignoreDefaultGroupUsers = false, ignoreDefaultGroupUsers = false,
ignoreSystemUsers = true ignoreSystemUsers = true
@ -108,7 +108,7 @@ class UserServiceTest :
fun `getByGroup() returns all the users with the given group from the repository`() { fun `getByGroup() returns all the users with the given group from the repository`() {
whenever(repository.findAllByGroup(group)).doReturn(entityList) whenever(repository.findAllByGroup(group)).doReturn(entityList)
val found = service.getByGroup(group) val found = logic.getByGroup(group)
assertTrue(found.containsAll(entityList)) assertTrue(found.containsAll(entityList))
assertTrue(entityList.containsAll(found)) 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`() { fun `getByGroup() returns an empty list when there is no user with the given group in the repository`() {
whenever(repository.findAllByGroup(group)).doReturn(listOf()) whenever(repository.findAllByGroup(group)).doReturn(listOf())
val found = service.getByGroup(group) val found = logic.getByGroup(group)
assertTrue(found.isEmpty()) assertTrue(found.isEmpty())
} }
@ -129,7 +129,7 @@ class UserServiceTest :
fun `getDefaultGroupUser() returns the default user of the given group from the repository`() { fun `getDefaultGroupUser() returns the default user of the given group from the repository`() {
whenever(repository.findByIsDefaultGroupUserIsTrueAndGroupIs(group)).doReturn(entityDefaultGroupUser) whenever(repository.findByIsDefaultGroupUserIsTrueAndGroupIs(group)).doReturn(entityDefaultGroupUser)
val found = service.getDefaultGroupUser(group) val found = logic.getDefaultGroupUser(group)
assertEquals(entityDefaultGroupUser, found) assertEquals(entityDefaultGroupUser, found)
} }
@ -140,7 +140,7 @@ class UserServiceTest :
whenever(repository.save(entity)).doReturn(entity) whenever(repository.save(entity)).doReturn(entity)
doReturn(false).whenever(repository).existsByFirstNameAndLastName(entity.firstName, entity.lastName) doReturn(false).whenever(repository).existsByFirstNameAndLastName(entity.firstName, entity.lastName)
val found = service.save(entity) val found = logic.save(entity)
verify(repository).save(entity) verify(repository).save(entity)
assertEquals(entity, found) assertEquals(entity, found)
@ -150,13 +150,13 @@ class UserServiceTest :
fun `save() throws AlreadyExistsException when firstName and lastName exists`() { fun `save() throws AlreadyExistsException when firstName and lastName exists`() {
doReturn(true).whenever(repository).existsByFirstNameAndLastName(entity.firstName, entity.lastName) doReturn(true).whenever(repository).existsByFirstNameAndLastName(entity.firstName, entity.lastName)
assertThrows<AlreadyExistsException> { service.save(entity) } assertThrows<AlreadyExistsException> { logic.save(entity) }
.assertErrorCode("fullName") .assertErrorCode("fullName")
} }
@Test @Test
override fun `save(dto) calls and returns save() with the created entity`() { override fun `save(dto) calls and returns save() with the created entity`() {
withBaseSaveDtoTest(entity, entitySaveDto, service, { withBaseSaveDtoTest(entity, entitySaveDto, logic, {
argThat { argThat {
this.id == entity.id && this.firstName == entity.firstName && this.lastName == entity.lastName this.id == entity.id && this.firstName == entity.firstName && this.lastName == entity.lastName
} }
@ -165,11 +165,11 @@ class UserServiceTest :
@Test @Test
fun `save(dto) calls and returns save() with the created user`() { 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) assertEquals(entitySaveDtoUser, found)
} }
@ -177,17 +177,17 @@ class UserServiceTest :
@Test @Test
override fun `update(dto) calls and returns update() with the created entity`() = override fun `update(dto) calls and returns update() with the created entity`() =
withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() }) withBaseUpdateDtoTest(entity, entityUpdateDto, logic, { any() })
@Test @Test
fun `update() throws AlreadyExistsException when a different user with the given first name and last name exists`() { 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( whenever(repository.findByFirstNameAndLastName(entity.firstName, entity.lastName)).doReturn(
entityDefaultGroupUser entityDefaultGroupUser
) )
doReturn(entity).whenever(service).getById(eq(entity.id), any(), any()) doReturn(entity).whenever(logic).getById(eq(entity.id), any(), any())
assertThrows<AlreadyExistsException> { assertThrows<AlreadyExistsException> {
service.update( logic.update(
entity, entity,
true, true,
ignoreSystemUsers = true ignoreSystemUsers = true
@ -197,11 +197,11 @@ class UserServiceTest :
} }
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class GroupServiceTest : class GroupLogicTest :
AbstractExternalNamedModelServiceTest<Group, GroupSaveDto, GroupUpdateDto, GroupService, GroupRepository>() { AbstractExternalNamedModelServiceTest<Group, GroupSaveDto, GroupUpdateDto, GroupLogic, GroupRepository>() {
private val userService: UserService = mock() private val userService: UserLogic = mock()
override val repository: GroupRepository = 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 entity: Group = group(id = 0L, name = "group")
override val anotherEntity: Group = group(id = 1L, name = "another 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`() { fun `getUsersForGroup() returns all users in the given group`() {
val group = group(id = 1L) 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)) 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.contains(groupUser))
assertTrue(found.size == 1) assertTrue(found.size == 1)
@ -235,9 +235,9 @@ class GroupServiceTest :
@Test @Test
fun `getUsersForGroup() returns empty collection when the given group contains any user`() { 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()) assertTrue(found.isEmpty())
} }
@ -252,7 +252,7 @@ class GroupServiceTest :
whenever(request.cookies).doReturn(cookies) whenever(request.cookies).doReturn(cookies)
whenever(userService.getById(eq(groupUserId), any(), any())).doReturn(groupUser) whenever(userService.getById(eq(groupUserId), any(), any())).doReturn(groupUser)
val found = service.getRequestDefaultGroup(request) val found = logic.getRequestDefaultGroup(request)
assertEquals(entity, found) assertEquals(entity, found)
} }
@ -263,7 +263,7 @@ class GroupServiceTest :
whenever(request.cookies).doReturn(arrayOf()) whenever(request.cookies).doReturn(arrayOf())
assertThrows<NoDefaultGroupException> { service.getRequestDefaultGroup(request) } assertThrows<NoDefaultGroupException> { logic.getRequestDefaultGroup(request) }
} }
// setResponseDefaultGroup() // setResponseDefaultGroup()
@ -273,9 +273,9 @@ class GroupServiceTest :
val response = MockHttpServletResponse() val response = MockHttpServletResponse()
whenever(userService.getDefaultGroupUser(entity)).doReturn(groupUser) 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) val found = response.getCookie(defaultGroupCookieName)
assertNotNull(found) assertNotNull(found)
@ -290,57 +290,57 @@ class GroupServiceTest :
@Test @Test
override fun `save(dto) calls and returns save() with the created entity`() { override fun `save(dto) calls and returns save() with the created entity`() {
withBaseSaveDtoTest(entity, entitySaveDto, service) withBaseSaveDtoTest(entity, entitySaveDto, logic)
} }
// update() // update()
@Test @Test
override fun `update(dto) calls and returns update() with the created entity`() = 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) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class UserUserDetailsServiceTest { class UserUserDetailsLogicTest {
private val userService: UserService = mock() private val userLogic: UserLogic = mock()
private val service = spy(UserDetailsServiceImpl(userService)) private val logic = spy(DefaultUserDetailsLogic(userLogic))
private val user = user(id = 0L) private val user = user(id = 0L)
@BeforeEach @BeforeEach
fun beforeEach() { fun beforeEach() {
reset(userService, service) reset(userLogic, logic)
} }
// loadUserByUsername() // loadUserByUsername()
@Test @Test
fun `loadUserByUsername() calls loadUserByUserId() with the given username as an id`() { 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))) 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 @Test
fun `loadUserByUsername() throws UsernameNotFoundException when no user with the given id exists`() { 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) userIdNotFoundException(user.id)
) )
assertThrows<UsernameNotFoundException> { service.loadUserByUsername(user.id.toString()) } assertThrows<UsernameNotFoundException> { logic.loadUserByUsername(user.id.toString()) }
} }
// loadUserByUserId // loadUserByUserId
@Test @Test
fun `loadUserByUserId() returns an User corresponding to the user with the given id`() { 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.id, found.username.toLong())
assertEquals(user.password, found.password) 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 com.nhaarman.mockitokotlin2.*
import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.model.*
@ -10,11 +10,16 @@ import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class CompanyServiceTest : class CompanyLogicTest :
AbstractExternalNamedModelServiceTest<Company, CompanySaveDto, CompanyUpdateDto, CompanyService, CompanyRepository>() { AbstractExternalNamedModelServiceTest<Company, CompanySaveDto, CompanyUpdateDto, CompanyLogic, CompanyRepository>() {
private val recipeService: RecipeService = mock() private val recipeLogic: RecipeLogic = mock()
override val repository: CompanyRepository = 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 entity: Company = company(id = 0L, name = "company")
override val anotherEntity: Company = company(id = 1L, name = "another company") override val anotherEntity: Company = company(id = 1L, name = "another company")
@ -24,7 +29,7 @@ class CompanyServiceTest :
@AfterEach @AfterEach
override fun afterEach() { override fun afterEach() {
reset(recipeService) reset(recipeLogic)
super.afterEach() super.afterEach()
} }
@ -32,18 +37,18 @@ class CompanyServiceTest :
@Test @Test
fun `isLinkedToRecipes() returns true when a given company is linked to one or more recipes`() { 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) assertTrue(found)
} }
@Test @Test
fun `isLinkedToRecipes() returns false when a given company is not linked to any recipe`() { 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) assertFalse(found)
} }
@ -52,14 +57,14 @@ class CompanyServiceTest :
@Test @Test
override fun `save(dto) calls and returns save() with the created entity`() { override fun `save(dto) calls and returns save() with the created entity`() {
withBaseSaveDtoTest(entity, entitySaveDto, service) withBaseSaveDtoTest(entity, entitySaveDto, logic)
} }
// update() // update()
@Test @Test
override fun `update(dto) calls and returns update() with the created entity`() = override fun `update(dto) calls and returns update() with the created entity`() =
withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() }) withBaseUpdateDtoTest(entity, entityUpdateDto, logic, { any() })
// delete() // 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.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.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 dev.fyloz.colorrecipesexplorer.utils.encrypt
import io.mockk.* import io.mockk.*
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach
@ -18,20 +18,19 @@ import kotlin.test.assertEquals
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
class ConfigurationServiceTest { class ConfigurationLogicTest {
private val fileService = mockk<WriteableFileService>() private val fileLogic = mockk<WriteableFileLogic>()
private val resourceFileService = mockk<ResourceFileService>() private val resourceFileLogic = mockk<ResourceFileLogic>()
private val configurationSource = mockk<ConfigurationSource>() private val configurationSource = mockk<ConfigurationSource>()
private val securityProperties = mockk<CreSecurityProperties> { private val securityProperties = mockk<CreSecurityProperties> {
every { configSalt } returns "d32270943af7e1cc" every { configSalt } returns "d32270943af7e1cc"
} }
private val service = spyk( private val logic = spyk(
ConfigurationServiceImpl( DefaultConfigurationLogic(
fileService, fileLogic,
resourceFileService, resourceFileLogic,
configurationSource, configurationSource,
securityProperties, securityProperties
mockk()
) )
) )
@ -44,17 +43,17 @@ class ConfigurationServiceTest {
@Test @Test
fun `getAll() gets the Configuration of each ConfigurationType`() { 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 { verify {
service.getAll() logic.getAll()
ConfigurationType.values().forEach { ConfigurationType.values().forEach {
service.get(it) logic.get(it)
} }
} }
confirmVerified(service) confirmVerified(logic)
} }
@Test @Test
@ -65,15 +64,15 @@ class ConfigurationServiceTest {
ConfigurationType.INSTANCE_ICON_SET 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) 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>() val type = firstArg<ConfigurationType>()
configuration(type, type.key) configuration(type, type.key)
} }
val found = service.getAll() val found = logic.getAll()
assertFalse { assertFalse {
found.any { found.any {
@ -82,12 +81,12 @@ class ConfigurationServiceTest {
} }
verify { verify {
service.getAll() logic.getAll()
ConfigurationType.values().forEach { ConfigurationType.values().forEach {
service.get(it) logic.get(it)
} }
} }
confirmVerified(service) confirmVerified(logic)
} }
@Test @Test
@ -101,24 +100,24 @@ class ConfigurationServiceTest {
.map { it.key } .map { it.key }
.reduce { acc, s -> "$acc$CONFIGURATION_FORMATTED_LIST_DELIMITER$s" } .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>() val key = firstArg<String>()
configuration(key.toConfigurationType(), key) configuration(key.toConfigurationType(), key)
} }
val found = service.getAll(formattedKeyList) val found = logic.getAll(formattedKeyList)
assertTrue { assertTrue {
found.all { it.type in configurationTypes } found.all { it.type in configurationTypes }
} }
verify { verify {
service.getAll(formattedKeyList) logic.getAll(formattedKeyList)
configurationTypes.forEach { configurationTypes.forEach {
service.get(it.key) logic.get(it.key)
} }
} }
confirmVerified(service) confirmVerified(logic)
} }
// get() // get()
@ -128,18 +127,18 @@ class ConfigurationServiceTest {
val type = ConfigurationType.INSTANCE_ICON_SET val type = ConfigurationType.INSTANCE_ICON_SET
val key = type.key val key = type.key
every { service.get(type) } answers { every { logic.get(type) } answers {
val type = firstArg<ConfigurationType>() val type = firstArg<ConfigurationType>()
configuration(type, type.key) configuration(type, type.key)
} }
service.get(key) logic.get(key)
verify { verify {
service.get(key) logic.get(key)
service.get(type) logic.get(type)
} }
confirmVerified(service) confirmVerified(logic)
} }
@Test @Test
@ -149,7 +148,7 @@ class ConfigurationServiceTest {
every { configurationSource.get(type) } returns configuration every { configurationSource.get(type) } returns configuration
val found = service.get(type) val found = logic.get(type)
assertEquals(configuration, found) assertEquals(configuration, found)
} }
@ -160,12 +159,12 @@ class ConfigurationServiceTest {
every { configurationSource.get(type) } returns null every { configurationSource.get(type) } returns null
with(assertThrows<ConfigurationNotSetException> { service.get(type) }) { with(assertThrows<ConfigurationNotSetException> { logic.get(type) }) {
assertEquals(type, this.type) assertEquals(type, this.type)
} }
verify { verify {
service.get(type) logic.get(type)
configurationSource.get(type) configurationSource.get(type)
} }
} }
@ -174,7 +173,7 @@ class ConfigurationServiceTest {
fun `get(type) throws InvalidConfigurationKeyException when the given ConfigurationType is encryption salt`() { fun `get(type) throws InvalidConfigurationKeyException when the given ConfigurationType is encryption salt`() {
val type = ConfigurationType.GENERATED_ENCRYPTION_SALT val type = ConfigurationType.GENERATED_ENCRYPTION_SALT
assertThrows<InvalidConfigurationKeyException> { service.get(type) } assertThrows<InvalidConfigurationKeyException> { logic.get(type) }
} }
@Test @Test
@ -187,7 +186,7 @@ class ConfigurationServiceTest {
every { configurationSource.get(type) } returns configuration every { configurationSource.get(type) } returns configuration
val found = service.get(type) val found = logic.get(type)
assertTrue { found is SecureConfiguration } assertTrue { found is SecureConfiguration }
} }
@ -200,9 +199,9 @@ class ConfigurationServiceTest {
content = "content" 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) assertEquals(configuration.content, found)
} }
@ -212,9 +211,9 @@ class ConfigurationServiceTest {
val type = ConfigurationType.DATABASE_PASSWORD val type = ConfigurationType.DATABASE_PASSWORD
val configuration = secureConfiguration(type) 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 @Test
@ -228,7 +227,7 @@ class ConfigurationServiceTest {
every { configurationSource.get(type) } returns configuration every { configurationSource.get(type) } returns configuration
val found = service.getSecure(type) val found = logic.getSecure(type)
assertEquals(content, found) assertEquals(content, found)
} }
@ -237,7 +236,7 @@ class ConfigurationServiceTest {
fun `getSecure(type) throws UnsupportedOperationException when configuration is not secure`() { fun `getSecure(type) throws UnsupportedOperationException when configuration is not secure`() {
val type = ConfigurationType.INSTANCE_NAME val type = ConfigurationType.INSTANCE_NAME
assertThrows<UnsupportedOperationException> { service.getSecure(type) } assertThrows<UnsupportedOperationException> { logic.getSecure(type) }
} }
private fun getConfiguredImageTest( private fun getConfiguredImageTest(
@ -247,9 +246,9 @@ class ConfigurationServiceTest {
) { ) {
val resource = mockk<Resource>() val resource = mockk<Resource>()
val configuration = configuration(configurationType, imageSet.toString()) 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 every { imageService.read(any()) } returns resource
test(resource) test(resource)
@ -258,7 +257,7 @@ class ConfigurationServiceTest {
@Test @Test
fun `getConfiguredIcon() gets icon from resources when INSTANCE_ICON_SET configuration is false`() { fun `getConfiguredIcon() gets icon from resources when INSTANCE_ICON_SET configuration is false`() {
getConfiguredImageTest(ConfigurationType.INSTANCE_ICON_SET, false) { resource -> getConfiguredImageTest(ConfigurationType.INSTANCE_ICON_SET, false) { resource ->
val found = service.getConfiguredIcon() val found = logic.getConfiguredIcon()
assertEquals(resource, found) assertEquals(resource, found)
} }
@ -267,7 +266,7 @@ class ConfigurationServiceTest {
@Test @Test
fun `getConfiguredIcon() gets icon from files when INSTANCE_ICON_SET configuration is true`() { fun `getConfiguredIcon() gets icon from files when INSTANCE_ICON_SET configuration is true`() {
getConfiguredImageTest(ConfigurationType.INSTANCE_ICON_SET, true) { resource -> getConfiguredImageTest(ConfigurationType.INSTANCE_ICON_SET, true) { resource ->
val found = service.getConfiguredIcon() val found = logic.getConfiguredIcon()
assertEquals(resource, found) assertEquals(resource, found)
} }
@ -276,7 +275,7 @@ class ConfigurationServiceTest {
@Test @Test
fun `getConfiguredLogo() gets logo from resources when INSTANCE_LOGO_SET is false`() { fun `getConfiguredLogo() gets logo from resources when INSTANCE_LOGO_SET is false`() {
getConfiguredImageTest(ConfigurationType.INSTANCE_LOGO_SET, false) { resource -> getConfiguredImageTest(ConfigurationType.INSTANCE_LOGO_SET, false) { resource ->
val found = service.getConfiguredLogo() val found = logic.getConfiguredLogo()
assertEquals(resource, found) assertEquals(resource, found)
} }
@ -285,7 +284,7 @@ class ConfigurationServiceTest {
@Test @Test
fun `getConfiguredLogo() gets logo from files when INSTANCE_LOGO_SET is true`() { fun `getConfiguredLogo() gets logo from files when INSTANCE_LOGO_SET is true`() {
getConfiguredImageTest(ConfigurationType.INSTANCE_LOGO_SET, true) { resource -> getConfiguredImageTest(ConfigurationType.INSTANCE_LOGO_SET, true) { resource ->
val found = service.getConfiguredLogo() val found = logic.getConfiguredLogo()
assertEquals(resource, found) assertEquals(resource, found)
} }
@ -297,7 +296,7 @@ class ConfigurationServiceTest {
every { configurationSource.set(any<Configuration>()) } just runs every { configurationSource.set(any<Configuration>()) } just runs
service.set(configuration) logic.set(configuration)
verify { verify {
configurationSource.set(configuration) configurationSource.set(configuration)
@ -316,7 +315,7 @@ class ConfigurationServiceTest {
every { configurationSource.set(any<Configuration>()) } just runs every { configurationSource.set(any<Configuration>()) } just runs
every { content.encrypt(any(), any()) } returns encryptedContent every { content.encrypt(any(), any()) } returns encryptedContent
service.set(configuration) logic.set(configuration)
verify { verify {
configurationSource.set(match<Configuration> { configurationSource.set(match<Configuration> {
@ -328,8 +327,8 @@ class ConfigurationServiceTest {
private fun setConfiguredImageTest(test: (MultipartFile) -> Unit) { private fun setConfiguredImageTest(test: (MultipartFile) -> Unit) {
val file = mockk<MultipartFile>() val file = mockk<MultipartFile>()
every { service.set(any<Configuration>()) } just runs every { logic.set(any<Configuration>()) } just runs
every { fileService.write(any<MultipartFile>(), any(), any()) } just runs every { fileLogic.write(any<MultipartFile>(), any(), any()) } just runs
test(file) test(file)
} }
@ -337,10 +336,10 @@ class ConfigurationServiceTest {
@Test @Test
fun `setConfiguredIcon() sets icon in files`() { fun `setConfiguredIcon() sets icon in files`() {
setConfiguredImageTest { file -> setConfiguredImageTest { file ->
service.setConfiguredIcon(file) logic.setConfiguredIcon(file)
verify { verify {
fileService.write(file, any(), true) fileLogic.write(file, any(), true)
} }
} }
} }
@ -350,10 +349,10 @@ class ConfigurationServiceTest {
val type = ConfigurationType.INSTANCE_ICON_SET val type = ConfigurationType.INSTANCE_ICON_SET
setConfiguredImageTest { file -> setConfiguredImageTest { file ->
service.setConfiguredIcon(file) logic.setConfiguredIcon(file)
verify { verify {
service.set(match<Configuration> { logic.set(match<Configuration> {
it.key == type.key && it.content == true.toString() it.key == type.key && it.content == true.toString()
}) })
} }
@ -363,10 +362,10 @@ class ConfigurationServiceTest {
@Test @Test
fun `setConfiguredLogo() sets logo in files`() { fun `setConfiguredLogo() sets logo in files`() {
setConfiguredImageTest { file -> setConfiguredImageTest { file ->
service.setConfiguredLogo(file) logic.setConfiguredLogo(file)
verify { verify {
fileService.write(file, any(), true) fileLogic.write(file, any(), true)
} }
} }
} }
@ -376,10 +375,10 @@ class ConfigurationServiceTest {
val type = ConfigurationType.INSTANCE_LOGO_SET val type = ConfigurationType.INSTANCE_LOGO_SET
setConfiguredImageTest { file -> setConfiguredImageTest { file ->
service.setConfiguredLogo(file) logic.setConfiguredLogo(file)
verify { verify {
service.set(match<Configuration> { logic.set(match<Configuration> {
it.key == type.key && it.content == true.toString() 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 com.nhaarman.mockitokotlin2.*
import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.model.*
@ -10,14 +10,14 @@ import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class InventoryServiceTest { class InventoryLogicTest {
private val materialService: MaterialService = mock() private val materialLogic: MaterialLogic = mock()
private val mixService: MixService = mock() private val mixLogic: MixLogic = mock()
private val service = spy(InventoryServiceImpl(materialService, mixService)) private val logic = spy(DefaultInventoryLogic(materialLogic, mixLogic))
@AfterEach @AfterEach
fun afterEach() { fun afterEach() {
reset(materialService, service) reset(materialLogic, logic)
} }
// add() // add()
@ -32,13 +32,13 @@ class InventoryServiceTest {
) )
val storedQuantity = 2000f 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>()) .add(any<MaterialQuantityDto>())
val found = service.add(materialQuantities) val found = logic.add(materialQuantities)
materialQuantities.forEach { materialQuantities.forEach {
verify(service).add(it) verify(logic).add(it)
assertTrue { found.any { updated -> updated.material == it.material && updated.quantity == storedQuantity + it.quantity } } 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`() { fun `add(materialQuantity) updates material's quantity`() {
withGivenQuantities(0f, 1000f) { withGivenQuantities(0f, 1000f) {
val updatedQuantity = it + this.quantity 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 }, argThat { this.id == this@withGivenQuantities.material },
eq(this.quantity) eq(this.quantity)
) )
@ -78,16 +78,16 @@ class InventoryServiceTest {
1L to 750f 1L to 750f
) )
whenever(mixService.getById(mix.id!!)).doReturn(mix) whenever(mixLogic.getById(mix.id!!)).doReturn(mix)
doAnswer { doAnswer {
(it.arguments[0] as Collection<MaterialQuantityDto>).map { materialQuantity -> (it.arguments[0] as Collection<MaterialQuantityDto>).map { materialQuantity ->
materialQuantityDto(materialId = materialQuantity.material, quantity = 0f) 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] } this.all { it.quantity == expectedQuantities[it.material] }
}) })
@ -106,13 +106,13 @@ class InventoryServiceTest {
) )
val storedQuantity = 5000f 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>()) .deduct(any<MaterialQuantityDto>())
val found = service.deduct(materialQuantities) val found = logic.deduct(materialQuantities)
materialQuantities.forEach { materialQuantities.forEach {
verify(service).deduct(it) verify(logic).deduct(it)
assertTrue { found.any { updated -> updated.material == it.material && updated.quantity == storedQuantity - it.quantity } } assertTrue { found.any { updated -> updated.material == it.material && updated.quantity == storedQuantity - it.quantity } }
} }
} }
@ -131,18 +131,18 @@ class InventoryServiceTest {
withGivenQuantities(inventoryQuantity, it) withGivenQuantities(inventoryQuantity, it)
} }
assertThrows<MultiplesNotEnoughInventoryException> { service.deduct(materialQuantities) } assertThrows<MultiplesNotEnoughInventoryException> { logic.deduct(materialQuantities) }
} }
@Test @Test
fun `deduct(materialQuantity) updates material's quantity`() { fun `deduct(materialQuantity) updates material's quantity`() {
withGivenQuantities(5000f, 1000f) { withGivenQuantities(5000f, 1000f) {
val updatedQuantity = it - this.quantity 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 }, argThat { this.id == this@withGivenQuantities.material },
eq(-this.quantity) eq(-this.quantity)
) )
@ -153,7 +153,7 @@ class InventoryServiceTest {
@Test @Test
fun `deduct(materialQuantity) throws NotEnoughInventoryException when there is not enough inventory of the given material`() { fun `deduct(materialQuantity) throws NotEnoughInventoryException when there is not enough inventory of the given material`() {
withGivenQuantities(0f, 1000f) { 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) 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) 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.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue import com.fasterxml.jackson.module.kotlin.readValue
import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties 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.UserDetails
import dev.fyloz.colorrecipesexplorer.model.account.UserOutputDto import dev.fyloz.colorrecipesexplorer.model.account.UserOutputDto
import dev.fyloz.colorrecipesexplorer.model.account.toOutputDto import dev.fyloz.colorrecipesexplorer.model.account.toOutputDto
import dev.fyloz.colorrecipesexplorer.model.account.user 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.base64encode
import dev.fyloz.colorrecipesexplorer.utils.isAround import dev.fyloz.colorrecipesexplorer.utils.isAround
import io.jsonwebtoken.Jwts import io.jsonwebtoken.Jwts
import io.jsonwebtoken.jackson.io.JacksonDeserializer import io.jsonwebtoken.jackson.io.JacksonDeserializer
import io.mockk.spyk import io.mockk.spyk
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import java.time.Instant import java.time.Instant
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
class JwtServiceTest { class JwtLogicTest {
private val objectMapper = jacksonObjectMapper() private val objectMapper = jacksonObjectMapper()
private val securityProperties = CreSecurityProperties().apply { private val securityProperties = CreSecurityProperties().apply {
jwtSecret = "XRRm7OflmFuCrOB2Xvmfsercih9DCKom" jwtSecret = "XRRm7OflmFuCrOB2Xvmfsercih9DCKom"
@ -33,7 +32,7 @@ class JwtServiceTest {
.build() .build()
} }
private val jwtService = spyk(JwtServiceImpl(objectMapper, securityProperties)) private val jwtService = spyk(DefaultJwtLogic(objectMapper, securityProperties))
private val user = user() private val user = user()
private val userOutputDto = user.toOutputDto() 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 com.nhaarman.mockitokotlin2.*
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
import dev.fyloz.colorrecipesexplorer.logic.files.WriteableFileLogic
import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.model.*
import dev.fyloz.colorrecipesexplorer.repository.MaterialRepository import dev.fyloz.colorrecipesexplorer.repository.MaterialRepository
import dev.fyloz.colorrecipesexplorer.service.files.WriteableFileService
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
@ -15,15 +15,15 @@ import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class MaterialServiceTest : class MaterialLogicTest :
AbstractExternalNamedModelServiceTest<Material, MaterialSaveDto, MaterialUpdateDto, MaterialService, MaterialRepository>() { AbstractExternalNamedModelServiceTest<Material, MaterialSaveDto, MaterialUpdateDto, MaterialLogic, MaterialRepository>() {
override val repository: MaterialRepository = mock() override val repository: MaterialRepository = mock()
private val recipeService: RecipeService = mock() private val recipeService: RecipeLogic = mock()
private val mixService: MixService = mock() private val mixService: MixLogic = mock()
private val materialTypeService: MaterialTypeService = mock() private val materialTypeService: MaterialTypeLogic = mock()
private val fileService: WriteableFileService = mock() private val fileService: WriteableFileLogic = mock()
override val service: MaterialService = override val logic: MaterialLogic =
spy(MaterialServiceImpl(repository, recipeService, mixService, materialTypeService, fileService, mock())) spy(DefaultMaterialLogic(repository, recipeService, mixService, materialTypeService, fileService, mock()))
override val entity: Material = material(id = 0L, name = "material") override val entity: Material = material(id = 0L, name = "material")
private val entityOutput = materialOutputDto(entity) 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`() { fun `existsByMaterialType() returns true when a material with the given material type exists in the repository`() {
whenever(repository.existsByMaterialType(materialType)).doReturn(true) whenever(repository.existsByMaterialType(materialType)).doReturn(true)
val found = service.existsByMaterialType(materialType) val found = logic.existsByMaterialType(materialType)
assertTrue(found) assertTrue(found)
} }
@ -55,7 +55,7 @@ class MaterialServiceTest :
fun `existsByMaterialType() returns false when no material with the given material type exists in the repository`() { fun `existsByMaterialType() returns false when no material with the given material type exists in the repository`() {
whenever(repository.existsByMaterialType(materialType)).doReturn(false) whenever(repository.existsByMaterialType(materialType)).doReturn(false)
val found = service.existsByMaterialType(materialType) val found = logic.existsByMaterialType(materialType)
assertFalse(found) assertFalse(found)
} }
@ -65,9 +65,9 @@ class MaterialServiceTest :
@Test @Test
fun `hasSimdut() returns false when simdutService_exists() returns false`() { fun `hasSimdut() returns false when simdutService_exists() returns false`() {
whenever(fileService.exists(any())).doReturn(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) assertFalse(found)
} }
@ -75,9 +75,9 @@ class MaterialServiceTest :
@Test @Test
fun `hasSimdut() returns true when simdutService_exists() returns true`() { fun `hasSimdut() returns true when simdutService_exists() returns true`() {
whenever(fileService.exists(any())).doReturn(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) assertTrue(found)
} }
@ -90,9 +90,9 @@ class MaterialServiceTest :
val mixTypeMaterialOutput = materialOutputDto(mixTypeMaterial) val mixTypeMaterialOutput = materialOutputDto(mixTypeMaterial)
val materialList = listOf(entity, 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)) assertTrue(found.contains(entityOutput))
assertFalse(found.contains(mixTypeMaterialOutput)) assertFalse(found.contains(mixTypeMaterialOutput))
@ -102,15 +102,15 @@ class MaterialServiceTest :
@Test @Test
fun `save() throws AlreadyExistsException when a material with the given name exists in the repository`() { 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") .assertErrorCode("name")
} }
@Test @Test
override fun `save(dto) calls and returns save() with the created entity`() { override fun `save(dto) calls and returns save() with the created entity`() {
withBaseSaveDtoTest(entity, entitySaveDto, service, { any() }) withBaseSaveDtoTest(entity, entitySaveDto, logic, { any() })
} }
@Test @Test
@ -119,9 +119,9 @@ class MaterialServiceTest :
val materialSaveDto = spy(materialSaveDto(simdutFile = mockMultipartFile)) val materialSaveDto = spy(materialSaveDto(simdutFile = mockMultipartFile))
doReturn(false).whenever(mockMultipartFile).isEmpty 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) verify(fileService).write(mockMultipartFile, entity.simdutFilePath, false)
} }
@ -134,9 +134,9 @@ class MaterialServiceTest :
val anotherMaterial = material(id = 1L, name = "name") val anotherMaterial = material(id = 1L, name = "name")
whenever(repository.findByName(material.name)).doReturn(anotherMaterial) 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") .assertErrorCode("name")
} }
@ -145,11 +145,11 @@ class MaterialServiceTest :
val mockSimdutFile = MockMultipartFile("simdut", byteArrayOf(1, 2, 3, 4, 5)) val mockSimdutFile = MockMultipartFile("simdut", byteArrayOf(1, 2, 3, 4, 5))
val materialUpdateDto = spy(materialUpdateDto(id = 0L, simdutFile = mockSimdutFile)) val materialUpdateDto = spy(materialUpdateDto(id = 0L, simdutFile = mockSimdutFile))
doReturn(entity).whenever(service).getById(any()) doReturn(entity).whenever(logic).getById(any())
doReturn(entity).whenever(service).update(any<Material>()) doReturn(entity).whenever(logic).update(any<Material>())
doReturn(entity).whenever(materialUpdateDto).toEntity() doReturn(entity).whenever(materialUpdateDto).toEntity()
service.update(materialUpdateDto) logic.update(materialUpdateDto)
verify(fileService).write(mockSimdutFile, entity.simdutFilePath, true) verify(fileService).write(mockSimdutFile, entity.simdutFilePath, true)
} }
@ -162,7 +162,7 @@ class MaterialServiceTest :
val quantity = 1234f val quantity = 1234f
val totalQuantity = material.inventoryQuantity + quantity val totalQuantity = material.inventoryQuantity + quantity
val found = service.updateQuantity(material, quantity) val found = logic.updateQuantity(material, quantity)
verify(repository).updateInventoryQuantityById(material.id!!, totalQuantity) verify(repository).updateInventoryQuantityById(material.id!!, totalQuantity)
assertEquals(totalQuantity, found) assertEquals(totalQuantity, found)
@ -180,9 +180,9 @@ class MaterialServiceTest :
recipe(id = 0L, mixes = mutableListOf(mix(mixType = mixType(id = 0L, material = mixTypeMaterial)))) recipe(id = 0L, mixes = mutableListOf(mix(mixType = mixType(id = 0L, material = mixTypeMaterial))))
whenever(recipeService.getById(recipe.id!!)).doReturn(recipe) 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(normalMaterial) in found)
assertTrue(materialOutputDto(mixTypeMaterial) in found) assertTrue(materialOutputDto(mixTypeMaterial) in found)
@ -202,9 +202,9 @@ class MaterialServiceTest :
recipe.mixes.add(mix) recipe.mixes.add(mix)
whenever(mixService.getById(mix.id!!)).doReturn(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(normalMaterial) in found)
assertTrue(materialOutputDto(mixTypeMaterial) 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 com.nhaarman.mockitokotlin2.*
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
@ -16,11 +16,11 @@ import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class MaterialTypeServiceTest : class MaterialTypeLogicTest :
AbstractExternalNamedModelServiceTest<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialTypeService, MaterialTypeRepository>() { AbstractExternalNamedModelServiceTest<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialTypeLogic, MaterialTypeRepository>() {
override val repository: MaterialTypeRepository = mock() override val repository: MaterialTypeRepository = mock()
private val materialService: MaterialService = mock() private val materialService: MaterialLogic = mock()
override val service: MaterialTypeService = spy(MaterialTypeServiceImpl(repository, materialService)) override val logic: MaterialTypeLogic = spy(DefaultMaterialTypeLogic(repository, materialService))
override val entity: MaterialType = materialType(id = 0L, name = "material type", prefix = "MAT") 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 anotherEntity: MaterialType = materialType(id = 1L, name = "another material type", prefix = "AMT")
override val entityWithEntityName: MaterialType = materialType(2L, name = entity.name, prefix = "EEN") 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`() { fun `existsByPrefix() returns true when a material type with the given prefix exists`() {
whenever(repository.existsByPrefix(entity.prefix)).doReturn(true) whenever(repository.existsByPrefix(entity.prefix)).doReturn(true)
val found = service.existsByPrefix(entity.prefix) val found = logic.existsByPrefix(entity.prefix)
assertTrue(found) assertTrue(found)
} }
@ -51,7 +51,7 @@ class MaterialTypeServiceTest :
fun `existsByPrefix() returns false when no material type with the given prefix exists`() { fun `existsByPrefix() returns false when no material type with the given prefix exists`() {
whenever(repository.existsByPrefix(entity.prefix)).doReturn(false) whenever(repository.existsByPrefix(entity.prefix)).doReturn(false)
val found = service.existsByPrefix(entity.prefix) val found = logic.existsByPrefix(entity.prefix)
assertFalse(found) assertFalse(found)
} }
@ -62,7 +62,7 @@ class MaterialTypeServiceTest :
fun `isUsedByMaterial() returns true when materialService_existsByMaterialType() returns true`() { fun `isUsedByMaterial() returns true when materialService_existsByMaterialType() returns true`() {
whenever(materialService.existsByMaterialType(entity)).doReturn(true) whenever(materialService.existsByMaterialType(entity)).doReturn(true)
val found = service.isUsedByMaterial(entity) val found = logic.isUsedByMaterial(entity)
assertTrue(found) assertTrue(found)
} }
@ -71,7 +71,7 @@ class MaterialTypeServiceTest :
fun `isUsedByMaterial() returns false when materialService_existsByMaterialType() returns false`() { fun `isUsedByMaterial() returns false when materialService_existsByMaterialType() returns false`() {
whenever(materialService.existsByMaterialType(entity)).doReturn(false) whenever(materialService.existsByMaterialType(entity)).doReturn(false)
val found = service.isUsedByMaterial(entity) val found = logic.isUsedByMaterial(entity)
assertFalse(found) assertFalse(found)
} }
@ -82,7 +82,7 @@ class MaterialTypeServiceTest :
fun `getAllSystemTypes() returns all system types`() { fun `getAllSystemTypes() returns all system types`() {
whenever(repository.findAllBySystemTypeIs(true)).doReturn(listOf(systemType, anotherSystemType)) whenever(repository.findAllBySystemTypeIs(true)).doReturn(listOf(systemType, anotherSystemType))
val found = service.getAllSystemTypes() val found = logic.getAllSystemTypes()
assertTrue(found.contains(systemType)) assertTrue(found.contains(systemType))
assertTrue(found.contains(anotherSystemType)) assertTrue(found.contains(anotherSystemType))
@ -94,7 +94,7 @@ class MaterialTypeServiceTest :
fun `getAllNonSystemTypes() returns all non system types`() { fun `getAllNonSystemTypes() returns all non system types`() {
whenever(repository.findAllBySystemTypeIs(false)).doReturn(listOf(entity, anotherEntity)) whenever(repository.findAllBySystemTypeIs(false)).doReturn(listOf(entity, anotherEntity))
val found = service.getAllNonSystemType() val found = logic.getAllNonSystemType()
assertTrue(found.contains(entity)) assertTrue(found.contains(entity))
assertTrue(found.contains(anotherEntity)) assertTrue(found.contains(anotherEntity))
@ -104,16 +104,16 @@ class MaterialTypeServiceTest :
@Test @Test
override fun `save(dto) calls and returns save() with the created entity`() { override fun `save(dto) calls and returns save() with the created entity`() {
withBaseSaveDtoTest(entity, entitySaveDto, service) withBaseSaveDtoTest(entity, entitySaveDto, logic)
} }
// saveMaterialType() // saveMaterialType()
@Test @Test
fun `saveMaterialType() throws AlreadyExistsException when a material type with the given prefix already exists`() { 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") .assertErrorCode("prefix")
} }
@ -121,16 +121,16 @@ class MaterialTypeServiceTest :
@Test @Test
override fun `update(dto) calls and returns update() with the created entity`() = 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`() { override fun `update() saves in the repository and returns the updated value`() {
whenever(repository.save(entity)).doReturn(entity) whenever(repository.save(entity)).doReturn(entity)
whenever(repository.findByName(entity.name)).doReturn(null) whenever(repository.findByName(entity.name)).doReturn(null)
whenever(repository.findByPrefix(entity.prefix)).doReturn(null) whenever(repository.findByPrefix(entity.prefix)).doReturn(null)
doReturn(true).whenever(service).existsById(entity.id!!) doReturn(true).whenever(logic).existsById(entity.id!!)
doReturn(entity).whenever(service).getById(entity.id!!) doReturn(entity).whenever(logic).getById(entity.id!!)
val found = service.update(entity) val found = logic.update(entity)
verify(repository).save(entity) verify(repository).save(entity)
assertEquals(entity, found) 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`() { 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.findByName(entity.name)).doReturn(null)
whenever(repository.findByPrefix(entity.prefix)).doReturn(null) whenever(repository.findByPrefix(entity.prefix)).doReturn(null)
doReturn(false).whenever(service).existsById(entity.id!!) doReturn(false).whenever(logic).existsById(entity.id!!)
doReturn(null).whenever(service).getById(entity.id!!) doReturn(null).whenever(logic).getById(entity.id!!)
assertThrows<NotFoundException> { service.update(entity) } assertThrows<NotFoundException> { logic.update(entity) }
.assertErrorCode() .assertErrorCode()
} }
override fun `update() throws AlreadyExistsException when an entity with the updated name exists`() { override fun `update() throws AlreadyExistsException when an entity with the updated name exists`() {
whenever(repository.findByName(entity.name)).doReturn(entityWithEntityName) whenever(repository.findByName(entity.name)).doReturn(entityWithEntityName)
whenever(repository.findByPrefix(entity.prefix)).doReturn(null) whenever(repository.findByPrefix(entity.prefix)).doReturn(null)
doReturn(true).whenever(service).existsById(entity.id!!) doReturn(true).whenever(logic).existsById(entity.id!!)
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") .assertErrorCode("name")
} }
@ -160,9 +160,9 @@ class MaterialTypeServiceTest :
fun `update() throws AlreadyExistsException when an entity with the updated prefix exists`() { fun `update() throws AlreadyExistsException when an entity with the updated prefix exists`() {
val anotherMaterialType = materialType(prefix = entity.prefix) val anotherMaterialType = materialType(prefix = entity.prefix)
whenever(repository.findByPrefix(entity.prefix)).doReturn(anotherMaterialType) 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") .assertErrorCode("prefix")
} }
@ -170,7 +170,7 @@ class MaterialTypeServiceTest :
fun `update() throws CannotUpdateException when updating a system material type`() { fun `update() throws CannotUpdateException when updating a system material type`() {
whenever(repository.existsByIdAndSystemTypeIsTrue(systemType.id!!)).doReturn(true) whenever(repository.existsByIdAndSystemTypeIsTrue(systemType.id!!)).doReturn(true)
assertThrows<CannotUpdateException> { service.update(systemType) } assertThrows<CannotUpdateException> { logic.update(systemType) }
} }
// delete() // delete()
@ -179,7 +179,7 @@ class MaterialTypeServiceTest :
fun `delete() throws CannotDeleteException when deleting a system material type`() { fun `delete() throws CannotDeleteException when deleting a system material type`() {
whenever(repository.existsByIdAndSystemTypeIsTrue(systemType.id!!)).doReturn(true) whenever(repository.existsByIdAndSystemTypeIsTrue(systemType.id!!)).doReturn(true)
assertThrows<CannotDeleteException> { service.delete(systemType) } assertThrows<CannotDeleteException> { logic.delete(systemType) }
} }
override fun `delete() deletes in the repository`() { 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 com.nhaarman.mockitokotlin2.*
import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.model.*
@ -10,14 +10,14 @@ import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @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() override val repository: MixRepository = mock()
private val recipeService: RecipeService = mock() private val recipeService: RecipeLogic = mock()
private val materialTypeService: MaterialTypeService = mock() private val materialTypeService: MaterialTypeLogic = mock()
private val mixMaterialService: MixMaterialService = mock() private val mixMaterialService: MixMaterialLogic = mock()
private val mixTypeService: MixTypeService = mock() private val mixTypeService: MixTypeLogic = mock()
override val service: MixService = override val logic: MixLogic =
spy(MixServiceImpl(repository, recipeService, materialTypeService, mixMaterialService, mixTypeService)) spy(DefaultMixLogic(repository, recipeService, materialTypeService, mixMaterialService, mixTypeService))
override val entity: Mix = mix(id = 0L, location = "location") override val entity: Mix = mix(id = 0L, location = "location")
override val anotherEntity: Mix = mix(id = 1L) override val anotherEntity: Mix = mix(id = 1L)
@ -39,7 +39,7 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
whenever(repository.findAllByMixType(mixType)).doReturn(entityList) whenever(repository.findAllByMixType(mixType)).doReturn(entityList)
val found = service.getAllByMixType(mixType) val found = logic.getAllByMixType(mixType)
assertEquals(entityList, found) assertEquals(entityList, found)
} }
@ -70,12 +70,12 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
mixType.material.materialType!! mixType.material.materialType!!
) )
).doReturn(mixType) ).doReturn(mixType)
doReturn(true).whenever(service).existsById(mixWithId.id!!) doReturn(true).whenever(logic).existsById(mixWithId.id!!)
doReturn(mixWithId).whenever(service).save(any<Mix>()) 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(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. // 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 op: MixUpdateDtoTestScope.() -> Unit
) { ) {
with(scope) { with(scope) {
doReturn(true).whenever(service).existsById(mix.id!!) doReturn(true).whenever(logic).existsById(mix.id!!)
doReturn(mix).whenever(service).getById(mix.id!!) doReturn(mix).whenever(logic).getById(mix.id!!)
doReturn(sharedMixType).whenever(service).mixTypeIsShared(mix.mixType) doReturn(sharedMixType).whenever(logic).mixTypeIsShared(mix.mixType)
doAnswer { it.arguments[0] }.whenever(service).update(any<Mix>()) doAnswer { it.arguments[0] }.whenever(logic).update(any<Mix>())
if (mixUpdateDto.materialTypeId != null) { if (mixUpdateDto.materialTypeId != null) {
whenever(materialTypeService.getById(materialType.id!!)).doReturn(materialType) 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`() { override fun `update(dto) calls and returns update() with the created entity`() {
val mixUpdateDto = spy(mixUpdateDto(id = 0L, name = null, materialTypeId = null)) val mixUpdateDto = spy(mixUpdateDto(id = 0L, name = null, materialTypeId = null))
doReturn(entity).whenever(service).getById(any()) doReturn(entity).whenever(logic).getById(any())
doReturn(entity).whenever(service).update(entity) 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) assertEquals(entity, found)
} }
@ -131,7 +131,7 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
whenever(mixTypeService.saveForNameAndMaterialType(mixUpdateDto.name!!, materialType)) whenever(mixTypeService.saveForNameAndMaterialType(mixUpdateDto.name!!, materialType))
.doReturn(newMixType) .doReturn(newMixType)
val found = service.update(mixUpdateDto) val found = logic.update(mixUpdateDto)
verify(mixTypeService).saveForNameAndMaterialType(mixUpdateDto.name!!, materialType) verify(mixTypeService).saveForNameAndMaterialType(mixUpdateDto.name!!, materialType)
@ -145,7 +145,7 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
whenever(mixTypeService.updateForNameAndMaterialType(mixType, mixUpdateDto.name!!, materialType)) whenever(mixTypeService.updateForNameAndMaterialType(mixType, mixUpdateDto.name!!, materialType))
.doReturn(newMixType) .doReturn(newMixType)
val found = service.update(mixUpdateDto) val found = logic.update(mixUpdateDto)
verify(mixTypeService).updateForNameAndMaterialType(mixType, mixUpdateDto.name!!, materialType) verify(mixTypeService).updateForNameAndMaterialType(mixType, mixUpdateDto.name!!, materialType)
@ -174,7 +174,7 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
}.toSet() }.toSet()
} }
val found = service.update(mixUpdateDto) val found = logic.update(mixUpdateDto)
mixMaterials.forEach { mixMaterials.forEach {
assertTrue { assertTrue {
@ -197,10 +197,10 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
mixLocationDto(mixId = 3, location = "Loc 3") mixLocationDto(mixId = 3, location = "Loc 3")
) )
service.updateLocations(locations) logic.updateLocations(locations)
locations.forEach { 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`() { fun `updateLocation() updates the location of a mix in the repository according to the given MixLocationDto`() {
val locationDto = mixLocationDto(mixId = 0L, location = "Location") val locationDto = mixLocationDto(mixId = 0L, location = "Location")
service.updateLocation(locationDto) logic.updateLocation(locationDto)
verify(repository).updateLocationById(locationDto.mixId, locationDto.location) 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 com.nhaarman.mockitokotlin2.*
import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.model.*
@ -12,10 +12,10 @@ import kotlin.test.assertNotEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class MixMaterialServiceTest : AbstractModelServiceTest<MixMaterial, MixMaterialService, MixMaterialRepository>() { class MixMaterialLogicTest : AbstractModelServiceTest<MixMaterial, MixMaterialLogic, MixMaterialRepository>() {
override val repository: MixMaterialRepository = mock() override val repository: MixMaterialRepository = mock()
private val materialService: MaterialService = mock() private val materialService: MaterialLogic = mock()
override val service: MixMaterialService = spy(MixMaterialServiceImpl(repository, materialService)) override val logic: MixMaterialLogic = spy(DefaultMixMaterialLogic(repository, materialService))
private val material: Material = material(id = 0L) private val material: Material = material(id = 0L)
override val entity: MixMaterial = mixMaterial(id = 0L, material = material, quantity = 1000f) 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`() { fun `existsByMaterial() returns true when a mix material with the given material exists`() {
whenever(repository.existsByMaterial(material)).doReturn(true) whenever(repository.existsByMaterial(material)).doReturn(true)
val found = service.existsByMaterial(material) val found = logic.existsByMaterial(material)
assertTrue(found) assertTrue(found)
} }
@ -36,7 +36,7 @@ class MixMaterialServiceTest : AbstractModelServiceTest<MixMaterial, MixMaterial
fun `existsByMaterial() returns false when no mix material with the given material exists`() { fun `existsByMaterial() returns false when no mix material with the given material exists`() {
whenever(repository.existsByMaterial(material)).doReturn(false) whenever(repository.existsByMaterial(material)).doReturn(false)
val found = service.existsByMaterial(material) val found = logic.existsByMaterial(material)
assertFalse(found) assertFalse(found)
} }
@ -60,12 +60,12 @@ class MixMaterialServiceTest : AbstractModelServiceTest<MixMaterial, MixMaterial
position = this.position 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 -> mixMaterialDtos.forEach { dto ->
verify(service).create(dto) verify(logic).create(dto)
assertTrue { assertTrue {
found.any { found.any {
it.material.id == dto.materialId && it.quantity == dto.quantity && it.position == dto.position 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) } whenever(materialService.getById(mixMaterialDto.materialId)).doAnswer { material(id = it.arguments[0] as Long) }
val found = service.create(mixMaterialDto) val found = logic.create(mixMaterialDto)
assertTrue { assertTrue {
found.material.id == mixMaterialDto.materialId && found.material.id == mixMaterialDto.materialId &&
@ -96,9 +96,9 @@ class MixMaterialServiceTest : AbstractModelServiceTest<MixMaterial, MixMaterial
val quantity = 5000f val quantity = 5000f
assertNotEquals(quantity, entity.quantity, message = "Quantities must not be equals for this test to works") 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) assertEquals(found.quantity, quantity)
} }
@ -156,13 +156,13 @@ class MixMaterialServiceTest : AbstractModelServiceTest<MixMaterial, MixMaterial
) )
assertThrows<InvalidFirstMixMaterial> { assertThrows<InvalidFirstMixMaterial> {
service.validateMixMaterials(mixMaterials) logic.validateMixMaterials(mixMaterials)
} }
} }
private fun assertInvalidMixMaterialsPositionsException(mixMaterials: Set<MixMaterial>, errorType: String) { private fun assertInvalidMixMaterialsPositionsException(mixMaterials: Set<MixMaterial>, errorType: String) {
val exception = assertThrows<InvalidMixMaterialsPositionsException> { val exception = assertThrows<InvalidMixMaterialsPositionsException> {
service.validateMixMaterials(mixMaterials) logic.validateMixMaterials(mixMaterials)
} }
assertTrue { exception.errors.size == 1 } 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 com.nhaarman.mockitokotlin2.*
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
@ -13,11 +13,10 @@ import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService, MixTypeRepository>() { class MixTypeLogicTest : AbstractNamedModelServiceTest<MixType, MixTypeLogic, MixTypeRepository>() {
override val repository: MixTypeRepository = mock() override val repository: MixTypeRepository = mock()
private val materialService: MaterialService = mock() private val materialService: MaterialLogic = mock()
private val mixService: MixService = mock() override val logic: MixTypeLogic = spy(DefaultMixTypeLogic(repository, materialService))
override val service: MixTypeService = spy(MixTypeServiceImpl(repository, materialService, mixService))
private val materialType: MaterialType = materialType() private val materialType: MaterialType = materialType()
private val material: Material = material(id = 0L, materialType = materialType) private val material: Material = material(id = 0L, materialType = materialType)
@ -38,7 +37,7 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
setOf(true, false).forEach { setOf(true, false).forEach {
whenever(repository.existsByNameAndMaterialType(entity.name, materialType)).doReturn(it) 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 } assertTrue { found == it }
} }
@ -50,7 +49,7 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
fun `getByMaterial() returns the mix type with the given material`() { fun `getByMaterial() returns the mix type with the given material`() {
whenever(repository.findByMaterial(material)).doReturn(entity) whenever(repository.findByMaterial(material)).doReturn(entity)
val found = service.getByMaterial(material) val found = logic.getByMaterial(material)
assertEquals(entity, found) 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`() { fun `getByMaterial() throws NotFoundException when no mix type with the given material exists`() {
whenever(repository.findByMaterial(material)).doReturn(null) whenever(repository.findByMaterial(material)).doReturn(null)
assertThrows<NotFoundException> { service.getByMaterial(material) } assertThrows<NotFoundException> { logic.getByMaterial(material) }
.assertErrorCode("name") .assertErrorCode("name")
} }
@ -69,7 +68,7 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
fun `getByNameAndMaterialType() returns the mix type with the given name and material type`() { fun `getByNameAndMaterialType() returns the mix type with the given name and material type`() {
whenever(repository.findByNameAndMaterialType(entity.name, materialType)).doReturn(entity) 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) assertEquals(entity, found)
} }
@ -77,24 +76,24 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
// getOrCreateForNameAndMaterialType() // getOrCreateForNameAndMaterialType()
@Test @Test
fun `getOrCreateForNameAndMaterialType() calls getForNameAndMaterialType() when a mix type with the given name and material type exists`() { 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(true).whenever(logic).existsByNameAndMaterialType(entity.name, materialType)
doReturn(entity).whenever(service).getByNameAndMaterialType(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) assertEquals(entity, found)
} }
@Test @Test
fun `getOrCreateForNameAndMaterialType() calls saveForNameAndMaterialType() when no mix type with the given name and material type exists`() { 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(false).whenever(logic).existsByNameAndMaterialType(entity.name, materialType)
doReturn(entity).whenever(service).saveForNameAndMaterialType(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) 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`() { fun `save() throws AlreadyExistsException when a material with the name of the new mix type exists`() {
whenever(materialService.existsByName(entity.name)).doReturn(true) whenever(materialService.existsByName(entity.name)).doReturn(true)
assertThrows<AlreadyExistsException> { service.save(entity) } assertThrows<AlreadyExistsException> { logic.save(entity) }
.assertErrorCode("name") .assertErrorCode("name")
} }
@ -116,11 +115,11 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
val name = entity.name val name = entity.name
val materialType = materialType() 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.name)
assertEquals(name, found.material.name) assertEquals(name, found.material.name)
@ -136,11 +135,11 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
val name = entity.name val name = entity.name
val materialType = materialType() 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(mixType.id, found.id)
assertEquals(name, found.name) 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 com.nhaarman.mockitokotlin2.*
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException 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.*
import dev.fyloz.colorrecipesexplorer.model.account.group import dev.fyloz.colorrecipesexplorer.model.account.group
import dev.fyloz.colorrecipesexplorer.repository.RecipeRepository 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 dev.fyloz.colorrecipesexplorer.utils.FilePath
import io.mockk.* import io.mockk.*
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach
@ -22,19 +22,19 @@ import java.time.Period
import kotlin.test.* import kotlin.test.*
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class RecipeServiceTest : class RecipeLogicTest :
AbstractExternalModelServiceTest<Recipe, RecipeSaveDto, RecipeUpdateDto, RecipeService, RecipeRepository>() { AbstractExternalModelServiceTest<Recipe, RecipeSaveDto, RecipeUpdateDto, RecipeLogic, RecipeRepository>() {
override val repository: RecipeRepository = mock() override val repository: RecipeRepository = mock()
private val companyService: CompanyService = mock() private val companyLogic: CompanyLogic = mock()
private val mixService: MixService = mock() private val mixService: MixLogic = mock()
private val groupService: GroupService = mock() private val groupService: GroupLogic = mock()
private val recipeStepService: RecipeStepService = mock() private val recipeStepService: RecipeStepLogic = mock()
private val configService: ConfigurationService = mock() private val configService: ConfigurationLogic = mock()
override val service: RecipeService = override val logic: RecipeLogic =
spy( spy(
RecipeServiceImpl( DefaultRecipeLogic(
repository, repository,
companyService, companyLogic,
mixService, mixService,
recipeStepService, recipeStepService,
groupService, groupService,
@ -51,7 +51,7 @@ class RecipeServiceTest :
@AfterEach @AfterEach
override fun afterEach() { override fun afterEach() {
reset(companyService, mixService) reset(companyLogic, mixService)
super.afterEach() super.afterEach()
} }
@ -61,7 +61,7 @@ class RecipeServiceTest :
fun `existsByCompany() returns true when at least one recipe exists for the given company`() { fun `existsByCompany() returns true when at least one recipe exists for the given company`() {
whenever(repository.existsByCompany(company)).doReturn(true) whenever(repository.existsByCompany(company)).doReturn(true)
val found = service.existsByCompany(company) val found = logic.existsByCompany(company)
assertTrue(found) assertTrue(found)
} }
@ -70,7 +70,7 @@ class RecipeServiceTest :
fun `existsByCompany() returns false when no recipe exists for the given company`() { fun `existsByCompany() returns false when no recipe exists for the given company`() {
whenever(repository.existsByCompany(company)).doReturn(false) whenever(repository.existsByCompany(company)).doReturn(false)
val found = service.existsByCompany(company) val found = logic.existsByCompany(company)
assertFalse(found) assertFalse(found)
} }
@ -82,7 +82,7 @@ class RecipeServiceTest :
setOf(true, false).forEach { setOf(true, false).forEach {
whenever(repository.existsByNameAndCompany(entity.name, company)).doReturn(it) 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) assertEquals(it, exists)
} }
@ -97,7 +97,7 @@ class RecipeServiceTest :
whenever(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(period.toString()) whenever(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(period.toString())
val approbationExpired = service.isApprobationExpired(recipe) val approbationExpired = logic.isApprobationExpired(recipe)
assertNotNull(approbationExpired) assertNotNull(approbationExpired)
assertFalse(approbationExpired) assertFalse(approbationExpired)
@ -110,7 +110,7 @@ class RecipeServiceTest :
whenever(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(period.toString()) whenever(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(period.toString())
val approbationExpired = service.isApprobationExpired(recipe) val approbationExpired = logic.isApprobationExpired(recipe)
assertNotNull(approbationExpired) assertNotNull(approbationExpired)
assertTrue(approbationExpired) assertTrue(approbationExpired)
@ -123,7 +123,7 @@ class RecipeServiceTest :
whenever(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(period.toString()) whenever(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(period.toString())
val approbationExpired = service.isApprobationExpired(recipe) val approbationExpired = logic.isApprobationExpired(recipe)
assertNull(approbationExpired) assertNull(approbationExpired)
} }
@ -136,7 +136,7 @@ class RecipeServiceTest :
whenever(repository.findAllByName(entity.name)).doReturn(recipes) whenever(repository.findAllByName(entity.name)).doReturn(recipes)
val found = service.getAllByName(entity.name) val found = logic.getAllByName(entity.name)
assertEquals(recipes, found) assertEquals(recipes, found)
} }
@ -148,7 +148,7 @@ class RecipeServiceTest :
val companies = listOf(entity, anotherEntity) val companies = listOf(entity, anotherEntity)
whenever(repository.findAllByCompany(company)).doReturn(companies) whenever(repository.findAllByCompany(company)).doReturn(companies)
val found = service.getAllByCompany(company) val found = logic.getAllByCompany(company)
assertEquals(companies, found) assertEquals(companies, found)
} }
@ -157,17 +157,17 @@ class RecipeServiceTest :
@Test @Test
override fun `save(dto) calls and returns save() with the created entity`() { override fun `save(dto) calls and returns save() with the created entity`() {
whenever(companyService.getById(company.id!!)).doReturn(company) whenever(companyLogic.getById(company.id!!)).doReturn(company)
doReturn(false).whenever(service).existsByNameAndCompany(entity.name, company) doReturn(false).whenever(logic).existsByNameAndCompany(entity.name, company)
withBaseSaveDtoTest(entity, entitySaveDto, service, { argThat { this.id == null && this.color == color } }) withBaseSaveDtoTest(entity, entitySaveDto, logic, { argThat { this.id == null && this.color == color } })
} }
@Test @Test
fun `save(dto) throw AlreadyExistsException when a recipe with the given name and company exists in the repository`() { 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) whenever(companyLogic.getById(company.id!!)).doReturn(company)
doReturn(true).whenever(service).existsByNameAndCompany(entity.name, 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") this.assertErrorCode("company-name")
} }
} }
@ -176,19 +176,19 @@ class RecipeServiceTest :
@Test @Test
override fun `update(dto) calls and returns update() with the created entity`() { override fun `update(dto) calls and returns update() with the created entity`() {
doReturn(false).whenever(service).existsByNameAndCompany(entity.name, company) doReturn(false).whenever(logic).existsByNameAndCompany(entity.name, company)
withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() }) withBaseUpdateDtoTest(entity, entityUpdateDto, logic, { any() })
} }
@Test @Test
fun `update(dto) throws AlreadyExistsException when a recipe exists for the given name and company`() { fun `update(dto) throws AlreadyExistsException when a recipe exists for the given name and company`() {
val name = "another recipe" val name = "another recipe"
doReturn(entity).whenever(service).getById(entity.id!!) doReturn(entity).whenever(logic).getById(entity.id!!)
doReturn(true).whenever(service).existsByNameAndCompany(name, company) doReturn(true).whenever(logic).existsByNameAndCompany(name, company)
doReturn(name).whenever(entityUpdateDto).name doReturn(name).whenever(entityUpdateDto).name
with(assertThrows<AlreadyExistsException> { service.update(entityUpdateDto) }) { with(assertThrows<AlreadyExistsException> { logic.update(entityUpdateDto) }) {
this.assertErrorCode("company-name") this.assertErrorCode("company-name")
} }
} }
@ -210,12 +210,12 @@ class RecipeServiceTest :
) )
val publicData = recipePublicDataDto(recipeId = recipe.id!!, notes = notes) val publicData = recipePublicDataDto(recipeId = recipe.id!!, notes = notes)
doReturn(recipe).whenever(service).getById(recipe.id!!) doReturn(recipe).whenever(logic).getById(recipe.id!!)
doAnswer { it.arguments[0] }.whenever(service).update(any<Recipe>()) 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 == 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.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 } assertTrue { this.groupsInformation.any { it.group.id == 3L } && this.groupsInformation.first { it.group.id == 3L }.note == null }
@ -225,7 +225,7 @@ class RecipeServiceTest :
} }
@Test @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( val publicData = recipePublicDataDto(
mixesLocation = setOf( mixesLocation = setOf(
mixLocationDto(mixId = 0L, location = "Loc 1"), mixLocationDto(mixId = 0L, location = "Loc 1"),
@ -233,10 +233,10 @@ class RecipeServiceTest :
) )
) )
service.updatePublicData(publicData) logic.updatePublicData(publicData)
verify(mixService).updateLocations(publicData.mixesLocation!!) verify(mixService).updateLocations(publicData.mixesLocation!!)
verify(service, times(0)).update(any<Recipe>()) verify(logic, times(0)).update(any<Recipe>())
} }
// addMix() // addMix()
@ -246,11 +246,11 @@ class RecipeServiceTest :
val mix = mix(id = 0L) val mix = mix(id = 0L)
val recipe = recipe(id = 0L, mixes = mutableListOf()) 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) assertEquals(recipe.id, found.id)
assertTrue(found.mixes.contains(mix)) assertTrue(found.mixes.contains(mix))
@ -264,11 +264,11 @@ class RecipeServiceTest :
val mix = mix(id = 0L, recipe = recipe) val mix = mix(id = 0L, recipe = recipe)
recipe.mixes.add(mix) 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) assertEquals(recipe.id, found.id)
assertFalse(found.mixes.contains(mix)) assertFalse(found.mixes.contains(mix))
@ -276,11 +276,11 @@ class RecipeServiceTest :
} }
private class RecipeImageServiceTestContext { private class RecipeImageServiceTestContext {
val fileService = mockk<WriteableFileService> { val fileService = mockk<WriteableFileLogic> {
every { write(any<MultipartFile>(), any(), any()) } just Runs every { write(any<MultipartFile>(), any(), any()) } just Runs
every { delete(any()) } just Runs every { delete(any()) } just Runs
} }
val recipeImageService = spyk(RecipeImageServiceImpl(fileService)) val recipeImageService = spyk(DefaultRecipeImageLogic(fileService))
val recipe = spyk(recipe()) val recipe = spyk(recipe())
val recipeImagesIds = setOf(1L, 10L, 21L) val recipeImagesIds = setOf(1L, 10L, 21L)
val recipeImagesNames = recipeImagesIds.map { it.imageName }.toSet() val recipeImagesNames = recipeImagesIds.map { it.imageName }.toSet()
@ -293,7 +293,7 @@ private class RecipeImageServiceTestContext {
get() = "${recipe.imagesDirectoryPath}/$this$RECIPE_IMAGE_EXTENSION" get() = "${recipe.imagesDirectoryPath}/$this$RECIPE_IMAGE_EXTENSION"
} }
class RecipeImageServiceTest { class RecipeImageLogicTest {
@AfterEach @AfterEach
internal fun afterEach() { internal fun afterEach() {
clearAllMocks() clearAllMocks()

View File

@ -1,4 +1,4 @@
package dev.fyloz.colorrecipesexplorer.service package dev.fyloz.colorrecipesexplorer.logic
import com.nhaarman.mockitokotlin2.* import com.nhaarman.mockitokotlin2.*
import dev.fyloz.colorrecipesexplorer.model.RecipeGroupInformation import dev.fyloz.colorrecipesexplorer.model.RecipeGroupInformation
@ -13,10 +13,10 @@ import org.junit.jupiter.api.assertThrows
import kotlin.test.assertTrue import kotlin.test.assertTrue
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class RecipeStepServiceTest : class RecipeStepLogicTest :
AbstractModelServiceTest<RecipeStep, RecipeStepService, RecipeStepRepository>() { AbstractModelServiceTest<RecipeStep, RecipeStepLogic, RecipeStepRepository>() {
override val repository: RecipeStepRepository = mock() 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 entity: RecipeStep = recipeStep(id = 0L, message = "message")
override val anotherEntity: RecipeStep = recipeStep(id = 1L, message = "another message") override val anotherEntity: RecipeStep = recipeStep(id = 1L, message = "another message")
@ -26,19 +26,19 @@ class RecipeStepServiceTest :
@Test @Test
fun `validateGroupInformationSteps() calls validateSteps() with the given RecipeGroupInformation steps`() { fun `validateGroupInformationSteps() calls validateSteps() with the given RecipeGroupInformation steps`() {
withGroupInformation { withGroupInformation {
service.validateGroupInformationSteps(this) logic.validateGroupInformationSteps(this)
verify(service).validateSteps(this.steps!!) verify(logic).validateSteps(this.steps!!)
} }
} }
@Test @Test
fun `validateGroupInformationSteps() throws InvalidGroupStepsPositionsException when validateSteps() throws an InvalidStepsPositionsException`() { fun `validateGroupInformationSteps() throws InvalidGroupStepsPositionsException when validateSteps() throws an InvalidStepsPositionsException`() {
withGroupInformation { withGroupInformation {
doAnswer { throw InvalidStepsPositionsException(setOf()) }.whenever(service).validateSteps(this.steps!!) doAnswer { throw InvalidStepsPositionsException(setOf()) }.whenever(logic).validateSteps(this.steps!!)
assertThrows<InvalidGroupStepsPositionsException> { assertThrows<InvalidGroupStepsPositionsException> {
service.validateGroupInformationSteps(this) logic.validateGroupInformationSteps(this)
} }
} }
} }
@ -100,7 +100,7 @@ class RecipeStepServiceTest :
private fun assertInvalidStepsPositionsException(steps: MutableSet<RecipeStep>, errorType: String) { private fun assertInvalidStepsPositionsException(steps: MutableSet<RecipeStep>, errorType: String) {
val exception = assertThrows<InvalidStepsPositionsException> { val exception = assertThrows<InvalidStepsPositionsException> {
service.validateSteps(steps) logic.validateSteps(steps)
} }
assertTrue { exception.errors.size == 1 } 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.ConfigurationType
import dev.fyloz.colorrecipesexplorer.model.configuration import dev.fyloz.colorrecipesexplorer.model.configuration
import dev.fyloz.colorrecipesexplorer.repository.TouchUpKitRepository 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.PdfDocument
import dev.fyloz.colorrecipesexplorer.utils.toByteArrayResource import dev.fyloz.colorrecipesexplorer.utils.toByteArrayResource
import io.mockk.* import io.mockk.*
@ -15,11 +15,11 @@ import kotlin.test.assertEquals
private class TouchUpKitServiceTestContext { private class TouchUpKitServiceTestContext {
val touchUpKitRepository = mockk<TouchUpKitRepository>() val touchUpKitRepository = mockk<TouchUpKitRepository>()
val fileService = mockk<WriteableFileService> { val fileService = mockk<WriteableFileLogic> {
every { write(any<ByteArrayResource>(), any(), any()) } just Runs every { write(any<ByteArrayResource>(), any(), any()) } just Runs
} }
val configService = mockk<ConfigurationService>(relaxed = true) val configService = mockk<ConfigurationLogic>(relaxed = true)
val touchUpKitService = spyk(TouchUpKitServiceImpl(fileService, configService, touchUpKitRepository)) val touchUpKitService = spyk(DefaultTouchUpKitLogic(fileService, configService, touchUpKitRepository))
val pdfDocumentData = mockk<ByteArrayResource>() val pdfDocumentData = mockk<ByteArrayResource>()
val pdfDocument = mockk<PdfDocument> { val pdfDocument = mockk<PdfDocument> {
mockkStatic(PdfDocument::toByteArrayResource) mockkStatic(PdfDocument::toByteArrayResource)
@ -28,7 +28,7 @@ private class TouchUpKitServiceTestContext {
} }
} }
class TouchUpKitServiceTest { class TouchUpKitLogicTest {
private val job = "job" private val job = "job"
@AfterEach @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.colorrecipesexplorer.utils.FilePath
import dev.fyloz.memorycache.MemoryCache 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.config.properties.CreProperties
import dev.fyloz.colorrecipesexplorer.utils.File import dev.fyloz.colorrecipesexplorer.utils.File
@ -21,11 +21,11 @@ private const val mockFilePath = "existingFile"
private val mockFilePathPath = Path.of(mockFilePath) private val mockFilePathPath = Path.of(mockFilePath)
private val mockFileData = byteArrayOf(0x1, 0x8, 0xa, 0xf) private val mockFileData = byteArrayOf(0x1, 0x8, 0xa, 0xf)
class FileServiceTest { class FileLogicTest {
private val fileCacheMock = mockk<FileCache> { private val fileCacheMock = mockk<FileCache> {
every { setExists(any(), any()) } just runs 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> { private val mockFile = mockk<File> {
every { file } returns mockk() 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 dev.fyloz.colorrecipesexplorer.utils.FilePath
import io.mockk.clearAllMocks import io.mockk.clearAllMocks
@ -14,10 +14,10 @@ import kotlin.test.assertEquals
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
class ResourceFileServiceTest { class ResourceFileLogicTest {
private val resourceLoader = mockk<ResourceLoader>() private val resourceLoader = mockk<ResourceLoader>()
private val service = spyk(ResourceFileService(resourceLoader)) private val logic = spyk(ResourceFileLogic(resourceLoader))
@AfterEach @AfterEach
fun afterEach() { fun afterEach() {
@ -26,7 +26,7 @@ class ResourceFileServiceTest {
private fun existsTest(shouldExists: Boolean, test: (String) -> Unit) { private fun existsTest(shouldExists: Boolean, test: (String) -> Unit) {
val path = "unit_test_resource" val path = "unit_test_resource"
with(service) { with(logic) {
every { fullPath(path) } returns mockk { every { fullPath(path) } returns mockk {
every { resource } returns mockk { every { resource } returns mockk {
every { exists() } returns shouldExists every { exists() } returns shouldExists
@ -40,7 +40,7 @@ class ResourceFileServiceTest {
@Test @Test
fun `exists() returns true when a resource exists at the given path`() { fun `exists() returns true when a resource exists at the given path`() {
existsTest(true) { path -> existsTest(true) { path ->
val found = service.exists(path) val found = logic.exists(path)
assertTrue { found } assertTrue { found }
} }
@ -49,7 +49,7 @@ class ResourceFileServiceTest {
@Test @Test
fun `exists() returns false when no resource exists at the given path`() { fun `exists() returns false when no resource exists at the given path`() {
existsTest(false) { path -> existsTest(false) { path ->
val found = service.exists(path) val found = logic.exists(path)
assertFalse { found } assertFalse { found }
} }
@ -60,7 +60,7 @@ class ResourceFileServiceTest {
every { exists() } returns shouldExists every { exists() } returns shouldExists
} }
val path = "unit_test_path" val path = "unit_test_path"
with(service) { with(logic) {
every { fullPath(path) } returns mockk { every { fullPath(path) } returns mockk {
every { resource } returns mockResource every { resource } returns mockResource
} }
@ -72,7 +72,7 @@ class ResourceFileServiceTest {
@Test @Test
fun `read() returns the resource at the given path`() { fun `read() returns the resource at the given path`() {
readTest(true) { resource, path -> readTest(true) { resource, path ->
val found = service.read(path) val found = logic.read(path)
assertEquals(resource, found) assertEquals(resource, found)
} }
@ -82,7 +82,7 @@ class ResourceFileServiceTest {
fun `read() throws FileNotFoundException when no resource exists at the given path`() { fun `read() throws FileNotFoundException when no resource exists at the given path`() {
readTest(false) { _, path -> readTest(false) { _, path ->
assertThrows<FileNotFoundException> { assertThrows<FileNotFoundException> {
service.read(path) logic.read(path)
} }
} }
} }
@ -92,7 +92,7 @@ class ResourceFileServiceTest {
val path = "unit_test_path" val path = "unit_test_path"
val expectedPath = "classpath:$path" val expectedPath = "classpath:$path"
val found = service.fullPath(path) val found = logic.fullPath(path)
assertEquals(expectedPath, found.value) assertEquals(expectedPath, found.value)
} }
@ -104,7 +104,7 @@ class ResourceFileServiceTest {
every { resourceLoader.getResource(filePath.value) } returns resource every { resourceLoader.getResource(filePath.value) } returns resource
with(service) { with(logic) {
val found = filePath.resource val found = filePath.resource
assertEquals(resource, found) assertEquals(resource, found)