diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/exception/RestException.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/exception/RestException.kt index 1bc62b7..7e64182 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/exception/RestException.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/exception/RestException.kt @@ -59,6 +59,17 @@ class AlreadyExistsException( extensions = extensions.apply { this[identifierName] = identifierValue }.toMap() ) +class CannotUpdateException( + errorCode: String, + title: String, + details: String +) : RestException( + errorCode = "cannotupdate-$errorCode", + title = title, + status = HttpStatus.BAD_REQUEST, + details = details +) + class CannotDeleteException( errorCode: String, title: String, diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/MaterialType.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/MaterialType.kt index d19ac34..7abc3b7 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/MaterialType.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/MaterialType.kt @@ -2,6 +2,7 @@ package dev.fyloz.colorrecipesexplorer.model import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException import dev.fyloz.colorrecipesexplorer.exception.CannotDeleteException +import dev.fyloz.colorrecipesexplorer.exception.CannotUpdateException import dev.fyloz.colorrecipesexplorer.exception.NotFoundException import dev.fyloz.colorrecipesexplorer.model.validation.NullOrNotBlank import dev.fyloz.colorrecipesexplorer.model.validation.NullOrSize @@ -105,6 +106,7 @@ fun materialTypeUpdateDto( private const val MATERIAL_TYPE_NOT_FOUND_EXCEPTION_TITLE = "Material type not found" private const val MATERIAL_TYPE_ALREADY_EXISTS_EXCEPTION_TITLE = "Material type already exists" private const val MATERIAL_TYPE_CANNOT_DELETE_EXCEPTION_TITLE = "Cannot delete material type" +private const val MATERIAL_TYPE_CANNOT_UPDATE_EXCEPTION_TITLE = "Cannot update material type" private const val MATERIAL_TYPE_EXCEPTION_ERROR_CODE = "materialtype" fun materialTypeIdNotFoundException(id: Long) = @@ -150,9 +152,23 @@ fun materialTypePrefixAlreadyExistsException(prefix: String) = "prefix" ) +fun cannotUpdateSystemMaterialTypeException(materialType: MaterialType) = + CannotUpdateException( + MATERIAL_TYPE_EXCEPTION_ERROR_CODE, + MATERIAL_TYPE_CANNOT_UPDATE_EXCEPTION_TITLE, + "Cannot update material type ${materialType.name} because it is a system material type" + ) + fun cannotDeleteMaterialTypeException(materialType: MaterialType) = CannotDeleteException( MATERIAL_TYPE_EXCEPTION_ERROR_CODE, MATERIAL_TYPE_CANNOT_DELETE_EXCEPTION_TITLE, "Cannot delete material type ${materialType.name} because one or more materials depends on it" ) + +fun cannotDeleteSystemMaterialTypeException(materialType: MaterialType) = + CannotDeleteException( + MATERIAL_TYPE_EXCEPTION_ERROR_CODE, + MATERIAL_TYPE_CANNOT_DELETE_EXCEPTION_TITLE, + "Cannot delete material type ${materialType.name} because it is a system material type" + ) diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/repository/MaterialTypeRepository.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/repository/MaterialTypeRepository.kt index a664876..d90b51e 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/repository/MaterialTypeRepository.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/repository/MaterialTypeRepository.kt @@ -9,6 +9,9 @@ interface MaterialTypeRepository : NamedJpaRepository { /** Checks if a material type exists with the given [prefix]. */ fun existsByPrefix(prefix: String): Boolean + /** Checks if a system material type with the given [id] exists. */ + fun existsByIdAndSystemTypeIsTrue(id: Long): Boolean + /** Gets all material types which are not system types. */ fun findAllBySystemTypeIs(value: Boolean): Collection diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialTypeService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialTypeService.kt index 8d0ce96..0b37703 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialTypeService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialTypeService.kt @@ -66,16 +66,24 @@ class MaterialTypeServiceImpl(repository: MaterialTypeRepository, private val ma } override fun update(entity: MaterialType): MaterialType { + if (repository.existsByIdAndSystemTypeIsTrue(entity.id!!)) { + throw cannotUpdateSystemMaterialTypeException(entity) + } + with(repository.findByPrefix(entity.prefix)) { if (this != null && id != entity.id) throw materialTypePrefixAlreadyExistsException(entity.prefix) } - return super.update(entity) + return super.update(entity) } override fun delete(entity: MaterialType) { - if (!repository.canBeDeleted(entity.id!!)) throw cannotDeleteMaterialTypeException(entity) + if (repository.existsByIdAndSystemTypeIsTrue(entity.id!!)) { + throw cannotDeleteSystemMaterialTypeException(entity) + } + + if (!repository.canBeDeleted(entity.id)) throw cannotDeleteMaterialTypeException(entity) super.delete(entity) } diff --git a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialTypeServiceTest.kt b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialTypeServiceTest.kt index 7d8a1dd..ea0a5f4 100644 --- a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialTypeServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialTypeServiceTest.kt @@ -2,6 +2,8 @@ package dev.fyloz.colorrecipesexplorer.service import com.nhaarman.mockitokotlin2.* import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException +import dev.fyloz.colorrecipesexplorer.exception.CannotDeleteException +import dev.fyloz.colorrecipesexplorer.exception.CannotUpdateException import dev.fyloz.colorrecipesexplorer.exception.NotFoundException import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.repository.MaterialTypeRepository @@ -164,8 +166,22 @@ class MaterialTypeServiceTest : .assertErrorCode("prefix") } + @Test + fun `update() throws CannotUpdateException when updating a system material type`() { + whenever(repository.existsByIdAndSystemTypeIsTrue(systemType.id!!)).doReturn(true) + + assertThrows { service.update(systemType) } + } + // delete() + @Test + fun `delete() throws CannotDeleteException when deleting a system material type`() { + whenever(repository.existsByIdAndSystemTypeIsTrue(systemType.id!!)).doReturn(true) + + assertThrows { service.delete(systemType) } + } + override fun `delete() deletes in the repository`() { whenCanBeDeleted { super.`delete() deletes in the repository`()