La création d'un mélange vérifie si le type de mélange existe avant de tenter de le créer.
This commit is contained in:
parent
16f4a36693
commit
81c9f82a9f
|
@ -1,15 +1,23 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.repository
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MixType
|
||||
import org.springframework.data.jpa.repository.Query
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
interface MixTypeRepository : NamedJpaRepository<MixType> {
|
||||
@Query("select case when(count(m) > 0) then true else false end from MixType m where m.name = :name and m.material.materialType = :materialType")
|
||||
fun existsByNameAndMaterialType(name: String, materialType: MaterialType): Boolean
|
||||
|
||||
/** Gets the mix type with the given [material]. */
|
||||
fun findByMaterial(material: Material): MixType?
|
||||
|
||||
/** Gets the [MixType] with the given [name] and [materialType]. */
|
||||
@Query("select m from MixType m where m.name = :name and m.material.materialType = :materialType")
|
||||
fun findByNameAndMaterialType(name: String, materialType: MaterialType): MixType?
|
||||
|
||||
@Query(
|
||||
"""
|
||||
select case when(count(m.id) > 0) then false else true end
|
||||
|
|
|
@ -34,7 +34,7 @@ class MixServiceImpl(
|
|||
override fun save(entity: MixSaveDto): Mix {
|
||||
val recipe = recipeService.getById(entity.recipeId)
|
||||
val materialType = materialTypeService.getById(entity.materialTypeId)
|
||||
val mixType = mixTypeService.createForNameAndMaterialType(entity.name, materialType)
|
||||
val mixType = mixTypeService.getOrCreateForNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
var mix = save(mix(recipe = recipe, mixType = mixType))
|
||||
val mixMaterials =
|
||||
|
@ -84,7 +84,7 @@ class MixServiceImpl(
|
|||
val mix = getById(entity.id)
|
||||
if (entity.name != null || entity.materialTypeId != null) {
|
||||
mix.mixType = if (mixTypeIsShared(mix.mixType)) {
|
||||
mixTypeService.createForNameAndMaterialType(
|
||||
mixTypeService.saveForNameAndMaterialType(
|
||||
entity.name ?: mix.mixType.name,
|
||||
if (entity.materialTypeId != null) materialTypeService.getById(entity.materialTypeId) else mix.mixType.material.materialType!!
|
||||
)
|
||||
|
|
|
@ -9,11 +9,20 @@ import org.springframework.context.annotation.Lazy
|
|||
import org.springframework.stereotype.Service
|
||||
|
||||
interface MixTypeService : NamedModelService<MixType, MixTypeRepository> {
|
||||
/** Checks if a [MixType] with the given [name] and [materialType] exists. */
|
||||
fun existsByNameAndMaterialType(name: String, materialType: MaterialType): Boolean
|
||||
|
||||
/** Gets the mix type with the given [material]. */
|
||||
fun getByMaterial(material: Material): MixType
|
||||
|
||||
/** Gets the [MixType] with the given [name] and [materialType]. */
|
||||
fun getByNameAndMaterialType(name: String, materialType: MaterialType): MixType
|
||||
|
||||
/** Returns a [MixType] for the given [name] and [materialType]. If a mix type with these does not already exists, it will be created. */
|
||||
fun getOrCreateForNameAndMaterialType(name: String, materialType: MaterialType): MixType
|
||||
|
||||
/** Returns a new and persisted [MixType] with the given [name] and [materialType]. */
|
||||
fun createForNameAndMaterialType(name: String, materialType: MaterialType): MixType
|
||||
fun saveForNameAndMaterialType(name: String, materialType: MaterialType): MixType
|
||||
|
||||
/** Returns the given [mixType] updated with the given [name] and [materialType]. */
|
||||
fun updateForNameAndMaterialType(mixType: MixType, name: String, materialType: MaterialType): MixType
|
||||
|
@ -26,16 +35,29 @@ class MixTypeServiceImpl(
|
|||
@Lazy val mixService: MixService
|
||||
) :
|
||||
AbstractNamedModelService<MixType, MixTypeRepository>(mixTypeRepository), MixTypeService {
|
||||
override fun existsByNameAndMaterialType(name: String, materialType: MaterialType): Boolean =
|
||||
repository.existsByNameAndMaterialType(name, materialType)
|
||||
|
||||
override fun getByMaterial(material: Material): MixType =
|
||||
repository.findByMaterial(material) ?: throw EntityNotFoundRestException(material.name)
|
||||
|
||||
override fun getByNameAndMaterialType(name: String, materialType: MaterialType): MixType =
|
||||
repository.findByNameAndMaterialType(name, materialType)
|
||||
?: throw EntityNotFoundRestException("$name/${materialType.name}")
|
||||
|
||||
override fun getOrCreateForNameAndMaterialType(name: String, materialType: MaterialType): MixType =
|
||||
if (existsByNameAndMaterialType(name, materialType))
|
||||
getByNameAndMaterialType(name, materialType)
|
||||
else
|
||||
saveForNameAndMaterialType(name, materialType)
|
||||
|
||||
override fun save(entity: MixType): MixType {
|
||||
if (materialService.existsByName(entity.name))
|
||||
throw EntityAlreadyExistsRestException(entity.name)
|
||||
return super.save(entity)
|
||||
}
|
||||
|
||||
override fun createForNameAndMaterialType(name: String, materialType: MaterialType): MixType =
|
||||
override fun saveForNameAndMaterialType(name: String, materialType: MaterialType): MixType =
|
||||
save(
|
||||
mixType(
|
||||
name = name,
|
||||
|
|
|
@ -36,6 +36,7 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
|
||||
// save()
|
||||
|
||||
@Test
|
||||
override fun `save(dto) calls and returns save() with the created entity`() {
|
||||
val recipe = recipe(id = entitySaveDto.recipeId)
|
||||
val materialType = materialType(id = entitySaveDto.materialTypeId)
|
||||
|
@ -54,7 +55,7 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
whenever(recipeService.getById(recipe.id!!)).doReturn(recipe)
|
||||
whenever(materialTypeService.getById(materialType.id!!)).doReturn(materialType)
|
||||
whenever(mixMaterialService.createFromMap(mixWithId, entitySaveDto.mixMaterials!!)).doReturn(mixMaterials)
|
||||
whenever(mixTypeService.createForNameAndMaterialType(mixType.name, mixType.material.materialType!!)).doReturn(
|
||||
whenever(mixTypeService.getOrCreateForNameAndMaterialType(mixType.name, mixType.material.materialType!!)).doReturn(
|
||||
mixType
|
||||
)
|
||||
doReturn(true).whenever(service).existsById(mixWithId.id!!)
|
||||
|
@ -68,7 +69,7 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
verify(recipeService).addMix(recipe, mix)
|
||||
|
||||
// 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(mixTypeService).createForNameAndMaterialType(mixType.name, mixType.material.materialType!!)
|
||||
verify(mixTypeService).getOrCreateForNameAndMaterialType(mixType.name, mixType.material.materialType!!)
|
||||
|
||||
assertEquals(mixWithMaterials, found)
|
||||
}
|
||||
|
@ -115,14 +116,14 @@ class MixServiceTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpda
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `update(dto) calls MixTypeService createForNameAndMaterialType() when mix type is shared`() {
|
||||
fun `update(dto) calls MixTypeService saveForNameAndMaterialType() when mix type is shared`() {
|
||||
mixUpdateDtoMixTypeTest(sharedMixType = true) {
|
||||
whenever(mixTypeService.createForNameAndMaterialType(mixUpdateDto.name!!, materialType))
|
||||
whenever(mixTypeService.saveForNameAndMaterialType(mixUpdateDto.name!!, materialType))
|
||||
.doReturn(newMixType)
|
||||
|
||||
val found = service.update(mixUpdateDto)
|
||||
|
||||
verify(mixTypeService).createForNameAndMaterialType(mixUpdateDto.name!!, materialType)
|
||||
verify(mixTypeService).saveForNameAndMaterialType(mixUpdateDto.name!!, materialType)
|
||||
|
||||
assertEquals(newMixType, found.mixType)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.junit.jupiter.api.AfterEach
|
|||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService, MixTypeRepository>() {
|
||||
|
@ -17,7 +18,8 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
|
|||
private val mixService: MixService = mock()
|
||||
override val service: MixTypeService = spy(MixTypeServiceImpl(repository, materialService, mixService))
|
||||
|
||||
private val material: Material = material(id = 0L)
|
||||
private val materialType: MaterialType = materialType()
|
||||
private val material: Material = material(id = 0L, materialType = materialType)
|
||||
override val entity: MixType = mixType(id = 0L, name = "mix type", material = material)
|
||||
override val anotherEntity: MixType = mixType(id = 1L, name = "another mix type")
|
||||
override val entityWithEntityName: MixType = mixType(id = 2L, name = entity.name)
|
||||
|
@ -28,6 +30,19 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
|
|||
super.afterEach()
|
||||
}
|
||||
|
||||
// existsByNameAndMaterialType
|
||||
|
||||
@Test
|
||||
fun `existsByNameAndMaterialType() returns repository's answer`() {
|
||||
setOf(true, false).forEach {
|
||||
whenever(repository.existsByNameAndMaterialType(entity.name, materialType)).doReturn(it)
|
||||
|
||||
val found = service.existsByNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
assertTrue { found == it }
|
||||
}
|
||||
}
|
||||
|
||||
// getByMaterial()
|
||||
|
||||
@Test
|
||||
|
@ -47,6 +62,42 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
|
|||
assertEquals(material.name, exception.value)
|
||||
}
|
||||
|
||||
// getByNameAndMaterialType()
|
||||
|
||||
@Test
|
||||
fun `getByNameAndMaterialType() returns the mix type with the given name and material type`() {
|
||||
whenever(repository.findByNameAndMaterialType(entity.name, materialType)).doReturn(entity)
|
||||
|
||||
val found = service.getByNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
assertEquals(entity, found)
|
||||
}
|
||||
|
||||
// getOrCreateForNameAndMaterialType()
|
||||
@Test
|
||||
fun `getOrCreateForNameAndMaterialType() calls getForNameAndMaterialType() when a mix type with the given name and material type exists`() {
|
||||
doReturn(true).whenever(service).existsByNameAndMaterialType(entity.name, materialType)
|
||||
doReturn(entity).whenever(service).getByNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
val found = service.getOrCreateForNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
verify(service).getByNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
assertEquals(entity, found)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getOrCreateForNameAndMaterialType() calls saveForNameAndMaterialType() when no mix type with the given name and material type exists`() {
|
||||
doReturn(false).whenever(service).existsByNameAndMaterialType(entity.name, materialType)
|
||||
doReturn(entity).whenever(service).saveForNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
val found = service.getOrCreateForNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
verify(service).saveForNameAndMaterialType(entity.name, materialType)
|
||||
|
||||
assertEquals(entity, found)
|
||||
}
|
||||
|
||||
// save()
|
||||
|
||||
@Test
|
||||
|
@ -57,16 +108,16 @@ class MixTypeServiceTest : AbstractNamedModelServiceTest<MixType, MixTypeService
|
|||
assertEquals(entity.name, exception.value)
|
||||
}
|
||||
|
||||
// createForNameAndMaterialType()
|
||||
// saveForNameAndMaterialType()
|
||||
|
||||
@Test
|
||||
fun `createForNameAndMaterialType() creates a save a valid mix type with the given name and material type`() {
|
||||
fun `saveForNameAndMaterialType() creates a save a valid mix type with the given name and material type`() {
|
||||
val name = entity.name
|
||||
val materialType = materialType()
|
||||
|
||||
doAnswer { it.arguments[0] }.whenever(service).save(any())
|
||||
|
||||
val found = service.createForNameAndMaterialType(name, materialType)
|
||||
val found = service.saveForNameAndMaterialType(name, materialType)
|
||||
|
||||
verify(service).save(any())
|
||||
|
||||
|
|
Loading…
Reference in New Issue