diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Recipe.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Recipe.kt index e11db17..3ead0ef 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Recipe.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Recipe.kt @@ -52,10 +52,10 @@ data class Recipe( val company: Company, @OneToMany(cascade = [CascadeType.ALL], mappedBy = "recipe") - val mixes: MutableCollection, + val mixes: MutableList, @OneToMany(cascade = [CascadeType.ALL], mappedBy = "recipe") - var steps: MutableCollection + var steps: List ) : Model { constructor() : this( null, @@ -199,8 +199,8 @@ fun recipe( remark: String = "remark", note: String = "", company: Company = company(), - mixes: MutableCollection = mutableListOf(), - steps: MutableCollection = mutableListOf(), + mixes: MutableList = mutableListOf(), + steps: List = listOf(), op: Recipe.() -> Unit = {} ) = Recipe(id, name, description, color, gloss, sample, approbationDate, remark, note, company, mixes, steps).apply(op) diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/RecipeService.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/RecipeService.kt index 3190407..4d3cb7f 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/RecipeService.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/RecipeService.kt @@ -33,7 +33,8 @@ interface RecipeService : ExternalModelService(recipeRepository), RecipeService { @@ -73,11 +74,24 @@ class RecipeServiceImpl( note = persistedRecipe.note, company = persistedRecipe.company, mixes = persistedRecipe.mixes, - steps = steps?.map { recipeStep(recipe = persistedRecipe, message = it.message) }?.toMutableList() ?: persistedRecipe.steps + steps = updateSteps(persistedRecipe, steps) ) }) } + private fun updateSteps(recipe: Recipe, steps: List?): List = + if (steps != null) { + val toDelete = recipe.steps.filter { it !in steps } + toDelete.forEach(stepService::delete) + recipe.steps + .filter { it !in toDelete } + steps + .map { recipeStep(recipe = recipe, message = it.message) } + .filter { it !in recipe.steps } + .toMutableList() + } else { + recipe.steps + } + @ExperimentalContracts override fun updatePublicData(publicDataDto: RecipePublicDataDto) { val recipe = getById(publicDataDto.id) diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AbstractServiceTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AbstractServiceTest.kt index 17d0ea3..7a0669f 100644 --- a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AbstractServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AbstractServiceTest.kt @@ -334,18 +334,18 @@ fun > withBaseUpdateDtoTest( entity: E, entityUpdateDto: U, service: ExternalModelService, - updateMockMatcher: E, - op: () -> Unit = {} + updateMockMatcher: () -> E, + op: E.() -> Unit = {} ) { - doAnswer { it.arguments[0] }.whenever(service).update(updateMockMatcher) + doAnswer { it.arguments[0] }.whenever(service).update(updateMockMatcher()) doReturn(entity).whenever(entityUpdateDto).toEntity() doReturn(entity).whenever(service).getById(entity.id!!) doReturn(true).whenever(service).existsById(entity.id!!) val found = service.update(entityUpdateDto) - verify(service).update(updateMockMatcher) + verify(service).update(updateMockMatcher()) assertEquals(entity, found) - op() + found.op() } diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AccountsServiceTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AccountsServiceTest.kt index ac9b44a..d932095 100644 --- a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AccountsServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AccountsServiceTest.kt @@ -168,8 +168,9 @@ class EmployeeServiceTest : // update() + @Test override fun `update(dto) calls and returns update() with the created entity`() = - withBaseUpdateDtoTest(entity, entityUpdateDto, service, any()) + withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() }) @Test fun `update() throws EntityAlreadyExistsRestException when a different employee with the given first name and last name exists`() { @@ -199,7 +200,7 @@ class EmployeeGroupServiceTest : override val entity: EmployeeGroup = employeeGroup(id = 0L, name = "group") override val anotherEntity: EmployeeGroup = employeeGroup(id = 1L, name = "another group") override val entitySaveDto: EmployeeGroupSaveDto = spy(employeeGroupSaveDto(name = "group")) - override val entityUpdateDto: EmployeeGroupUpdateDto = spy(employeeGroupUpdateDto(id = 0L, name = "groupL")) + override val entityUpdateDto: EmployeeGroupUpdateDto = spy(employeeGroupUpdateDto(id = 0L, name = "group")) override val entityWithEntityName: EmployeeGroup = employeeGroup(id = 2L, name = entity.name) private val groupEmployeeId = 1000000L + entity.id!! @@ -397,8 +398,9 @@ class EmployeeGroupServiceTest : // update() + @Test override fun `update(dto) calls and returns update() with the created entity`() = - withBaseUpdateDtoTest(entity, entityUpdateDto, service, any()) + withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() }) } class EmployeeUserDetailsServiceTest { diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/CompanyServiceTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/CompanyServiceTest.kt index ebf45ce..f80b657 100644 --- a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/CompanyServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/CompanyServiceTest.kt @@ -20,7 +20,7 @@ class CompanyServiceTest : override val anotherEntity: Company = company(id = 1L, name = "another company") override val entityWithEntityName: Company = company(id = 2L, name = entity.name) override val entitySaveDto: CompanySaveDto = spy(companySaveDto()) - override val entityUpdateDto: CompanyUpdateDto = spy(companyUpdateDto(id = entity.id!!)) + override val entityUpdateDto: CompanyUpdateDto = spy(companyUpdateDto(id = entity.id!!, name = null)) @AfterEach override fun afterEach() { @@ -50,8 +50,9 @@ class CompanyServiceTest : // update() + @Test override fun `update(dto) calls and returns update() with the created entity`() = - withBaseUpdateDtoTest(entity, entityUpdateDto, service, any()) + withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() }) // delete() diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialTypeServiceTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialTypeServiceTest.kt index 10a2fee..5986cff 100644 --- a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialTypeServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialTypeServiceTest.kt @@ -108,8 +108,9 @@ class MaterialTypeServiceTest : // update() + @Test override fun `update(dto) calls and returns update() with the created entity`() = - withBaseUpdateDtoTest(entity, entityUpdateDto, service, any()) + withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() }) override fun `update() saves in the repository and returns the updated value`() { whenever(repository.save(entity)).doReturn(entity) diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/RecipeServiceTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/RecipeServiceTest.kt index 65a604c..91a534c 100644 --- a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/RecipeServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/RecipeServiceTest.kt @@ -8,6 +8,7 @@ import dev.fyloz.trial.colorrecipesexplorer.service.files.FilesService import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows +import org.mockito.Mockito import org.springframework.mock.web.MockMultipartFile import java.io.File import java.nio.file.NoSuchFileException @@ -20,7 +21,8 @@ class RecipeServiceTest : override val repository: RecipeRepository = mock() private val companyService: CompanyService = mock() private val mixService: MixService = mock() - override val service: RecipeService = spy(RecipeServiceImpl(repository, companyService, mixService)) + private val stepService: RecipeStepService = mock() + override val service: RecipeService = spy(RecipeServiceImpl(repository, companyService, mixService, stepService)) private val company: Company = company(id = 0L) override val entity: Recipe = recipe(id = 0L, name = "recipe", company = company) @@ -28,6 +30,13 @@ class RecipeServiceTest : override val entitySaveDto: RecipeSaveDto = spy(recipeSaveDto(name = entity.name, companyId = entity.company.id!!)) override val entityUpdateDto: RecipeUpdateDto = spy(recipeUpdateDto(id = entity.id!!, name = entity.name)) + @AfterEach + override fun afterEach() { + reset(companyService, mixService, stepService) + super.afterEach() + } + + // existsByCompany() @Test @@ -69,9 +78,36 @@ class RecipeServiceTest : } // update() - + @Test override fun `update(dto) calls and returns update() with the created entity`() = - withBaseUpdateDtoTest(entity, entityUpdateDto, service, any()) + withBaseUpdateDtoTest(entity, entityUpdateDto, service, { any() }) + + @Test + fun `update(dto) remove unused steps`() { + val steps = listOf( + recipeStep(message = "step 1"), + recipeStep(message = "step 2"), + recipeStep(message = "step 3"), + recipeStep(message = "step 4"), + recipeStep(message = "step 5"), + recipeStep(message = "step 6"), + recipeStep(message = "step 7"), + recipeStep(message = "step 8") + ) + val originalSteps = steps.subList(0, 5) + val updatedSteps = steps.subList(2, 7) + val deletedSteps = steps.subList(0, 1) + val recipe = recipe(id = 0L, steps = originalSteps) + val dto = spy(recipeUpdateDto(id = recipe.id!!, steps = updatedSteps)) + + withBaseUpdateDtoTest(recipe, dto, service, { any() }) { + verify(stepService).delete(argThat { this in deletedSteps }) + + assertTrue { + this.steps.containsAll(updatedSteps) + } + } + } // updatePublicData()