diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MixMaterialService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MixMaterialService.kt index 3bcab80..f65a7a6 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MixMaterialService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MixMaterialService.kt @@ -17,6 +17,8 @@ interface MixMaterialService : ModelService /** Updates the [quantity] of the given [mixMaterial]. */ fun updateQuantity(mixMaterial: MixMaterial, quantity: Float): MixMaterial + + fun validateMixMaterials(mixMaterials: Set) } @Service diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeStepService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeStepService.kt index 4cae4c9..fadae3c 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeStepService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeStepService.kt @@ -7,16 +7,15 @@ import org.springframework.http.HttpStatus import org.springframework.stereotype.Service interface RecipeStepService : ModelService { - /** - * Validates if the steps of the given [groupInformation] obey the following criteria: - * - * * The position of the steps is greater or equals to 1 - * * Each position is unique in the collection - * * There is no gap between positions - * - * If any of those criteria are not met, an [InvalidStepsPositionsException] will be thrown. - */ + /** Validates the steps of the given [groupInformation], according to the criteria of [validateSteps]. */ fun validateGroupInformationSteps(groupInformation: RecipeGroupInformation) + + /** + * Validates if the given [steps]. To be valid, the position of each step must be greater or equals to 1 and unique in the set. + * There must also be no gap between the positions. + * If any of those criteria are not met, an [InvalidGroupStepsPositionsException] will be thrown. + */ + fun validateSteps(steps: Set) } @Service @@ -27,11 +26,16 @@ class RecipeStepServiceImpl(recipeStepRepository: RecipeStepRepository) : override fun idAlreadyExistsException(id: Long) = recipeStepIdAlreadyExistsException(id) override fun validateGroupInformationSteps(groupInformation: RecipeGroupInformation) { - val steps = groupInformation.steps - val group = groupInformation.group + if (groupInformation.steps == null) return - if (steps == null) return + try { + validateSteps(groupInformation.steps!!.toSet()) + } catch (validationException: InvalidStepsPositionsException) { + throw InvalidGroupStepsPositionsException(groupInformation.group, validationException) + } + } + override fun validateSteps(steps: Set) { val sortedSteps = steps.sortedBy { it.position } val errors = mutableSetOf() @@ -44,7 +48,7 @@ class RecipeStepServiceImpl(recipeStepRepository: RecipeStepRepository) : sortedSteps .groupBy { it.position } .filter { it.value.count() > 1 } - .map { duplicatedStepsPositions(it.key, group) } + .map { duplicatedStepsPositions(it.key) } // Check if there is any gap between steps positions // Knowing that steps are sorted by position, if the position of the step is not index + 1, there is a gap between them @@ -56,9 +60,9 @@ class RecipeStepServiceImpl(recipeStepRepository: RecipeStepRepository) : // Find all errors and throw if there is any if (isFirstStepPositionInvalid()) errors += invalidFirstStepPosition(sortedSteps[0]) errors += getDuplicatedPositionsErrors() - if (errors.isEmpty() && hasGapBetweenPositions()) errors += gapBetweenStepsPositions(group) + if (errors.isEmpty() && hasGapBetweenPositions()) errors += gapBetweenStepsPositions() if (errors.isNotEmpty()) { - throw InvalidStepsPositionsException(group, errors) + throw InvalidStepsPositionsException(errors) } } } @@ -69,43 +73,50 @@ data class InvalidStepsPositionsError( ) class InvalidStepsPositionsException( - val group: EmployeeGroup, val errors: Set -) : - RestException( - "invalid-recipestep-position", - "Invalid steps position", - HttpStatus.BAD_REQUEST, - "The position of steps for the group ${group.name} are invalid", - mapOf( - "group" to group.name, - "groupId" to group.id!!, - "invalidSteps" to errors - ) +) : RestException( + "invalid-recipestep-position", + "Invalid steps positions", + HttpStatus.BAD_REQUEST, + "The position of steps are invalid", + mapOf( + "invalidSteps" to errors ) +) + +class InvalidGroupStepsPositionsException( + val group: EmployeeGroup, + val exception: InvalidStepsPositionsException +) : RestException( + "invalid-groupinformation-recipestep-position", + "Invalid steps position", + HttpStatus.BAD_REQUEST, + "The position of steps for the group ${group.name} are invalid", + mapOf( + "group" to group.name, + "groupId" to group.id!!, + "invalidSteps" to exception.errors + ) +) const val INVALID_FIRST_STEP_POSITION_ERROR_CODE = "first" const val DUPLICATED_STEPS_POSITIONS_ERROR_CODE = "duplicated" const val GAP_BETWEEN_STEPS_POSITIONS_ERROR_CODE = "gap" -private fun invalidFirstStepPosition( - step: RecipeStep -) = InvalidStepsPositionsError( - INVALID_FIRST_STEP_POSITION_ERROR_CODE, - "The position ${step.position} is under the minimum of 1" -) +private fun invalidFirstStepPosition(step: RecipeStep) = + InvalidStepsPositionsError( + INVALID_FIRST_STEP_POSITION_ERROR_CODE, + "The position ${step.position} is under the minimum of 1" + ) -private fun duplicatedStepsPositions( - position: Int, - group: EmployeeGroup -) = InvalidStepsPositionsError( - DUPLICATED_STEPS_POSITIONS_ERROR_CODE, - "The position $position is duplicated in the group ${group.name}" -) +private fun duplicatedStepsPositions(position: Int) = + InvalidStepsPositionsError( + DUPLICATED_STEPS_POSITIONS_ERROR_CODE, + "The position $position is duplicated" + ) -private fun gapBetweenStepsPositions( - group: EmployeeGroup -) = InvalidStepsPositionsError( - GAP_BETWEEN_STEPS_POSITIONS_ERROR_CODE, - "The positions for the steps of the group ${group.name} have gaps between them" -) +private fun gapBetweenStepsPositions() = + InvalidStepsPositionsError( + GAP_BETWEEN_STEPS_POSITIONS_ERROR_CODE, + "There is a gap between steps positions" + ) diff --git a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeStepServiceTest.kt b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeStepServiceTest.kt index acafb28..5f6b43b 100644 --- a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeStepServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeStepServiceTest.kt @@ -28,7 +28,7 @@ class RecipeStepServiceTest : recipeStep(id = 3L, position = 3) ) ) { - val exception = assertThrows { + val exception = assertThrows { service.validateGroupInformationSteps(this) } @@ -47,7 +47,7 @@ class RecipeStepServiceTest : recipeStep(id = 3L, position = 3) ) ) { - val exception = assertThrows { + val exception = assertThrows { service.validateGroupInformationSteps(this) } @@ -66,7 +66,7 @@ class RecipeStepServiceTest : recipeStep(id = 3L, position = 5) ) ) { - val exception = assertThrows { + val exception = assertThrows { service.validateGroupInformationSteps(this) }