diff --git a/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResult.java b/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResult.java index f9165a809d..1b803c3800 100644 --- a/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResult.java +++ b/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResult.java @@ -49,9 +49,6 @@ public abstract class KeyResult implements WriteableInterface { @Column(name = "key_result_type", insertable = false, updatable = false) private String keyResultType; - @OneToMany(fetch = FetchType.LAZY, mappedBy = "keyResult", cascade = CascadeType.ALL) - private List actionList; - @Transient private boolean writeable; @@ -131,14 +128,6 @@ private void setKeyResultType(String keyResultType) { this.keyResultType = keyResultType; } - public List getActionList() { - return actionList; - } - - public void setActionList(List actionList) { - this.actionList = actionList; - } - @Override public boolean isWriteable() { return writeable; @@ -154,7 +143,7 @@ public String toString() { return "KeyResult{" + "id=" + id + ", version=" + version + ", objective=" + objective + ", title='" + title + '\'' + ", description='" + description + '\'' + ", owner=" + owner + ", createdBy=" + createdBy + ", createdOn=" + createdOn + ", modifiedOn=" + modifiedOn + ", keyResultType='" + keyResultType - + ", actionList=" + actionList + ", writeable=" + writeable + '\'' + '}'; + + ", writeable=" + writeable + '\'' + '}'; } @Override @@ -169,8 +158,7 @@ public boolean equals(Object o) { && Objects.equals(description, keyResult.description) && Objects.equals(owner, keyResult.owner) && Objects.equals(createdBy, keyResult.createdBy) && Objects.equals(createdOn, keyResult.createdOn) && Objects.equals(modifiedOn, keyResult.modifiedOn) - && Objects.equals(keyResultType, keyResult.keyResultType) - && Objects.equals(actionList, keyResult.actionList); + && Objects.equals(keyResultType, keyResult.keyResultType); } @Override @@ -185,8 +173,7 @@ public int hashCode() { createdBy, createdOn, modifiedOn, - keyResultType, - actionList); + keyResultType); } protected KeyResult() { @@ -203,7 +190,6 @@ protected KeyResult(Builder builder) { setCreatedOn(builder.createdOn); setModifiedOn(builder.modifiedOn); setKeyResultType(builder.keyResultType); - setActionList(builder.actionList); } @SuppressWarnings(value = "unchecked") diff --git a/backend/src/main/java/ch/puzzle/okr/service/business/ObjectiveBusinessService.java b/backend/src/main/java/ch/puzzle/okr/service/business/ObjectiveBusinessService.java index 25fa83d7cc..fa74874faf 100644 --- a/backend/src/main/java/ch/puzzle/okr/service/business/ObjectiveBusinessService.java +++ b/backend/src/main/java/ch/puzzle/okr/service/business/ObjectiveBusinessService.java @@ -1,25 +1,27 @@ package ch.puzzle.okr.service.business; -import static ch.puzzle.okr.Constants.KEY_RESULT_TYPE_METRIC; -import static ch.puzzle.okr.Constants.KEY_RESULT_TYPE_ORDINAL; - import ch.puzzle.okr.models.Action; import ch.puzzle.okr.models.Objective; import ch.puzzle.okr.models.authorization.AuthorizationUser; import ch.puzzle.okr.models.keyresult.KeyResult; import ch.puzzle.okr.models.keyresult.KeyResultMetric; import ch.puzzle.okr.models.keyresult.KeyResultOrdinal; +import ch.puzzle.okr.service.persistence.ActionPersistenceService; import ch.puzzle.okr.service.persistence.ObjectivePersistenceService; import ch.puzzle.okr.service.validation.ObjectiveValidationService; import jakarta.transaction.Transactional; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Objects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; + +import static ch.puzzle.okr.Constants.KEY_RESULT_TYPE_METRIC; +import static ch.puzzle.okr.Constants.KEY_RESULT_TYPE_ORDINAL; + @Service public class ObjectiveBusinessService implements BusinessServiceInterface { private static final Logger logger = LoggerFactory.getLogger(ObjectiveBusinessService.class); @@ -27,15 +29,17 @@ public class ObjectiveBusinessService implements BusinessServiceInterface duplicateActionList(KeyResult oldKeyResult, KeyResult newKeyResult) { - List actionList = oldKeyResult.getActionList(); - if (actionList != null) { - actionList = actionList - .stream() - .map(e -> Action.Builder - .builder() - .withKeyResult(newKeyResult) - .isChecked(e.isChecked()) - .withAction(e.getActionPoint()) - .withPriority(e.getPriority()) - .withVersion(e.getVersion()) - .build()) - .toList(); - } - return actionList; - } @Transactional public void deleteEntityById(Long id) { diff --git a/backend/src/main/java/ch/puzzle/okr/service/persistence/ActionPersistenceService.java b/backend/src/main/java/ch/puzzle/okr/service/persistence/ActionPersistenceService.java index 2ceb3685fe..2441658a4b 100644 --- a/backend/src/main/java/ch/puzzle/okr/service/persistence/ActionPersistenceService.java +++ b/backend/src/main/java/ch/puzzle/okr/service/persistence/ActionPersistenceService.java @@ -1,12 +1,14 @@ package ch.puzzle.okr.service.persistence; -import static ch.puzzle.okr.Constants.ACTION; - import ch.puzzle.okr.models.Action; +import ch.puzzle.okr.models.keyresult.KeyResult; import ch.puzzle.okr.repository.ActionRepository; -import java.util.List; import org.springframework.stereotype.Service; +import java.util.List; + +import static ch.puzzle.okr.Constants.ACTION; + @Service public class ActionPersistenceService extends PersistenceBase { @@ -22,4 +24,15 @@ public String getModelName() { public List getActionsByKeyResultIdOrderByPriorityAsc(Long keyResultId) { return getRepository().getActionsByKeyResultIdOrderByPriorityAsc(keyResultId); } + + public void duplicateActionList(KeyResult oldKeyResult, KeyResult newKeyResult) { + List actionList = getActionsByKeyResultIdOrderByPriorityAsc(oldKeyResult.getId()); + if (actionList != null) { + actionList.forEach(action -> { + action.setKeyResult(newKeyResult); + action.resetId(); + this.save(action); + }); + } + } } diff --git a/backend/src/test/java/ch/puzzle/okr/service/business/ObjectiveBusinessServiceTest.java b/backend/src/test/java/ch/puzzle/okr/service/business/ObjectiveBusinessServiceTest.java index 3c2a2e2b89..7d8ec200d1 100644 --- a/backend/src/test/java/ch/puzzle/okr/service/business/ObjectiveBusinessServiceTest.java +++ b/backend/src/test/java/ch/puzzle/okr/service/business/ObjectiveBusinessServiceTest.java @@ -13,6 +13,7 @@ import ch.puzzle.okr.models.keyresult.KeyResult; import ch.puzzle.okr.models.keyresult.KeyResultMetric; import ch.puzzle.okr.models.keyresult.KeyResultOrdinal; +import ch.puzzle.okr.service.persistence.ActionPersistenceService; import ch.puzzle.okr.service.persistence.ObjectivePersistenceService; import ch.puzzle.okr.service.validation.ObjectiveValidationService; import java.time.LocalDateTime; @@ -43,6 +44,8 @@ class ObjectiveBusinessServiceTest { CompletedBusinessService completedBusinessService; @Mock ObjectiveValidationService validator = Mockito.mock(ObjectiveValidationService.class); + @Mock + ActionPersistenceService actionPersistenceService; private static final AuthorizationUser authorizationUser = defaultAuthorizationUser(); private final Team team1 = Team.Builder.builder().withId(1L).withName("Team1").build(); @@ -281,39 +284,6 @@ void shouldDuplicateOrdinalKeyResult() { verify(keyResultBusinessService, times(1)).createEntity(any(KeyResult.class), any(AuthorizationUser.class)); } - @DisplayName("Should duplicate ActionList") - @Test - void shouldDuplicateActionList() { - KeyResult oldKeyResult = KeyResultMetric.Builder.builder().withId(1L).build(); - KeyResult newKeyResult = KeyResultMetric.Builder.builder().withId(2L).build(); - - Action action = Action.Builder - .builder() - .withKeyResult(oldKeyResult) - .withPriority(1) - .withVersion(1) - .isChecked(true) - .withAction("Action Point 1") - .build(); - - oldKeyResult.setActionList(List.of(action)); - - newKeyResult.setActionList(objectiveBusinessService.duplicateActionList(oldKeyResult, newKeyResult)); - - // assert that id changes to new key result - assertNotEquals(newKeyResult.getActionList().getFirst().getKeyResult().getId(), - oldKeyResult.getActionList().getFirst().getKeyResult().getId()); - - // assert that all other attributes stay the same - assertThat(newKeyResult.getActionList().getFirst()) - .extracting("priority", "version", "checked", "actionPoint") - .containsExactly(oldKeyResult.getActionList().getFirst().getPriority(), - oldKeyResult.getActionList().getFirst().getVersion(), - oldKeyResult.getActionList().getFirst().isChecked(), - oldKeyResult.getActionList().getFirst().getActionPoint()); - - } - @DisplayName("Should get all key result associated with the objective on getAllKeyResultsByObjective()") @Test void shouldGetAllKeyResultsByObjective() { diff --git a/backend/src/test/java/ch/puzzle/okr/service/persistence/ActionPersistenceServiceIT.java b/backend/src/test/java/ch/puzzle/okr/service/persistence/ActionPersistenceServiceIT.java index b4abf2abc4..7a2fff0c29 100644 --- a/backend/src/test/java/ch/puzzle/okr/service/persistence/ActionPersistenceServiceIT.java +++ b/backend/src/test/java/ch/puzzle/okr/service/persistence/ActionPersistenceServiceIT.java @@ -1,18 +1,14 @@ package ch.puzzle.okr.service.persistence; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; -import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY; - import ch.puzzle.okr.dto.ErrorDto; import ch.puzzle.okr.exception.OkrResponseStatusException; import ch.puzzle.okr.models.Action; import ch.puzzle.okr.models.Objective; +import ch.puzzle.okr.models.keyresult.KeyResult; import ch.puzzle.okr.models.keyresult.KeyResultMetric; import ch.puzzle.okr.multitenancy.TenantContext; import ch.puzzle.okr.test.SpringIntegrationTest; import ch.puzzle.okr.test.TestHelper; -import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -20,8 +16,16 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.server.ResponseStatusException; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.when; +import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY; + @SpringIntegrationTest class ActionPersistenceServiceIT { + private static final String UPDATED_ACTION = "Updated Action"; Action createdAction; @Autowired private ActionPersistenceService actionPersistenceService; @@ -48,8 +52,6 @@ private static Action createAction(Long id, int version) { .build(); } - private static final String UPDATED_ACTION = "Updated Action"; - @BeforeEach void setUp() { TenantContext.setCurrentTenant(TestHelper.SCHEMA_PITC); @@ -107,7 +109,7 @@ void shouldThrowExceptionWhenSaveIsCalledOnAlreadyUpdatedAction() { changedAction.setActionPoint(UPDATED_ACTION); OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, - () -> actionPersistenceService.save(changedAction)); + () -> actionPersistenceService.save(changedAction)); List expectedErrors = List.of(new ErrorDto("DATA_HAS_BEEN_UPDATED", List.of("Action"))); assertEquals(UNPROCESSABLE_ENTITY, exception.getStatusCode()); @@ -119,7 +121,7 @@ void shouldThrowExceptionWhenSaveIsCalledOnAlreadyUpdatedAction() { @Test void shouldReturnListOfAllActionsWhenFindAllIsCalled() { List actions = actionPersistenceService.findAll(); - + System.out.println(actions.getFirst()); assertEquals(11, actions.size()); } @@ -160,4 +162,31 @@ void shouldDeleteActionById() { actions = actionPersistenceService.findAll(); assertEquals(11, actions.size()); } + + @DisplayName("Should duplicate ActionList") + @Test + void shouldDuplicateActionList() { + KeyResult newKeyResult = KeyResultMetric.Builder.builder().withId(9L).build(); + KeyResult oldKeyResult = KeyResultMetric.Builder.builder().withId(6L).build(); + + actionPersistenceService.duplicateActionList(oldKeyResult, newKeyResult); + + List newKeyResultActionList = actionPersistenceService.getActionsByKeyResultIdOrderByPriorityAsc(newKeyResult.getId()); + List oldKeyResultActionList = actionPersistenceService.getActionsByKeyResultIdOrderByPriorityAsc(oldKeyResult.getId()); + + // assert that id changes to new key result + assertNotEquals(newKeyResultActionList.getFirst().getKeyResult().getId(), + oldKeyResultActionList.getFirst().getKeyResult().getId()); + + // assert that all other attributes stay the same + assertThat(newKeyResultActionList.getFirst()) + .extracting("priority", "version", "checked", "actionPoint") + .containsExactly( + oldKeyResultActionList.getFirst().getPriority(), + oldKeyResultActionList.getFirst().getVersion(), + oldKeyResultActionList.getFirst().isChecked(), + oldKeyResultActionList.getFirst().getActionPoint()); + + } + }