diff --git a/lib/taskana-core-test/src/test/java/acceptance/task/claim/ClaimTaskAccTest.java b/lib/taskana-core-test/src/test/java/acceptance/task/claim/ClaimTaskAccTest.java index 08a02a3c39..dea2c18200 100644 --- a/lib/taskana-core-test/src/test/java/acceptance/task/claim/ClaimTaskAccTest.java +++ b/lib/taskana-core-test/src/test/java/acceptance/task/claim/ClaimTaskAccTest.java @@ -43,7 +43,7 @@ import pro.taskana.workbasket.api.models.WorkbasketSummary; @TaskanaIntegrationTest -class ClaimTaskAccTest { +class ClaimTaskAccTest implements TaskanaConfigurationModifier { @TaskanaInject TaskService taskService; @TaskanaInject ClassificationService classificationService; @TaskanaInject WorkbasketService workbasketService; @@ -56,6 +56,11 @@ class ClaimTaskAccTest { WorkbasketSummary wbWithoutReadTasks; WorkbasketSummary wbWithoutRead; + @Override + public TaskanaConfiguration.Builder modify(TaskanaConfiguration.Builder builder) { + return builder.addAdditionalUserInfo(true); + } + @WithAccessId(user = "businessadmin") @BeforeAll void setup() throws Exception { @@ -371,6 +376,52 @@ void should_CancelClaimTask_When_TaskIsClaimed() throws Exception { assertThat(unclaimedTask.getOwnerLongName()).isNull(); } + @WithAccessId(user = "user-1-2") + @Test + void should_KeepOwnerAndOwnerLongName_When_CancelClaimWithKeepOwner() throws Exception { + Task claimedTask = + TaskBuilder.newTask() + .state(TaskState.CLAIMED) + .claimed(Instant.now()) + .owner("user-1-2") + .classificationSummary(defaultClassificationSummary) + .workbasketSummary(defaultWorkbasketSummary) + .primaryObjRef(defaultObjectReference) + .buildAndStore(taskService); + + Task unclaimedTask = taskService.cancelClaim(claimedTask.getId(), true); + + assertThat(unclaimedTask).isNotNull(); + assertThat(unclaimedTask.getState()).isEqualTo(TaskState.READY); + assertThat(unclaimedTask.getClaimed()).isNull(); + assertThat(unclaimedTask.isRead()).isTrue(); + assertThat(unclaimedTask.getOwner()).isEqualTo("user-1-2"); + assertThat(unclaimedTask.getOwnerLongName()).isEqualTo("Long name of user-1-2"); + } + + @WithAccessId(user = "user-1-2") + @Test + void should_KeepOwnerAndOwnerLongName_When_ForceCancelClaimWithKeepOwner() throws Exception { + Task claimedTask = + TaskBuilder.newTask() + .state(TaskState.CLAIMED) + .claimed(Instant.now()) + .owner("user-1-2") + .classificationSummary(defaultClassificationSummary) + .workbasketSummary(defaultWorkbasketSummary) + .primaryObjRef(defaultObjectReference) + .buildAndStore(taskService); + + Task unclaimedTask = taskService.forceCancelClaim(claimedTask.getId(), true); + + assertThat(unclaimedTask).isNotNull(); + assertThat(unclaimedTask.getState()).isEqualTo(TaskState.READY); + assertThat(unclaimedTask.getClaimed()).isNull(); + assertThat(unclaimedTask.isRead()).isTrue(); + assertThat(unclaimedTask.getOwner()).isEqualTo("user-1-2"); + assertThat(unclaimedTask.getOwnerLongName()).isEqualTo("Long name of user-1-2"); + } + @WithAccessId(user = "user-1-2") @Test void should_CancelClaimTask_When_TaskIsInReview() throws Exception { diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/api/TaskService.java b/lib/taskana-core/src/main/java/pro/taskana/task/api/TaskService.java index 0c51e9b956..d83214238c 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/task/api/TaskService.java +++ b/lib/taskana-core/src/main/java/pro/taskana/task/api/TaskService.java @@ -220,6 +220,44 @@ Task cancelClaim(String taskId) NotAuthorizedOnWorkbasketException, InvalidTaskStateException; + /** + * Cancel the claim of an existing {@linkplain Task} if it was claimed by the current user before. + * + * @param taskId the {@linkplain Task#getId() id} of the {@linkplain Task} which should be + * unclaimed + * @param keepOwner If set to true, will keep the {@linkplain Task#getOwner()} and {@linkplain + * Task#getOwnerLongName()} + * @return the unclaimed {@linkplain Task} + * @throws TaskNotFoundException if the {@linkplain Task} with taskId was not found + * @throws InvalidTaskStateException if the {@linkplain Task} is already in one of the {@linkplain + * TaskState#END_STATES} + * @throws InvalidOwnerException if the {@linkplain Task} is claimed by another user + * @throws NotAuthorizedOnWorkbasketException if the current user has no {@linkplain + * WorkbasketPermission#READ} for the {@linkplain Workbasket} the {@linkplain Task} is in + */ + Task cancelClaim(String taskId, boolean keepOwner) + throws TaskNotFoundException, + InvalidOwnerException, + NotAuthorizedOnWorkbasketException, + InvalidTaskStateException; + + /** + * Cancel the claim of an existing {@linkplain Task} even if it was claimed by another user. + * + * @param taskId the {@linkplain Task#getId() id} of the {@linkplain Task} which should be + * unclaimed + * @param keepOwner If set to true, will keep the {@linkplain Task#getOwner()} and {@linkplain + * Task#getOwnerLongName()} + * @return the unclaimed {@linkplain Task} + * @throws TaskNotFoundException if the {@linkplain Task} with taskId was not found + * @throws InvalidTaskStateException if the {@linkplain Task} is already in one of the {@linkplain + * TaskState#END_STATES} + * @throws NotAuthorizedOnWorkbasketException if the current user has no {@linkplain + * WorkbasketPermission#READ} for the {@linkplain Workbasket} the {@linkplain Task} is in + */ + Task forceCancelClaim(String taskId, boolean keepOwner) + throws TaskNotFoundException, NotAuthorizedOnWorkbasketException, InvalidTaskStateException; + /** * Cancel the claim of an existing {@linkplain Task} even if it was claimed by another user. * diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java index 07a98dcd98..08e3baaac2 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java @@ -160,30 +160,55 @@ public TaskServiceImpl( @Override public Task claim(String taskId) - throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException, + throws TaskNotFoundException, + InvalidOwnerException, + NotAuthorizedOnWorkbasketException, InvalidTaskStateException { return claim(taskId, false); } @Override public Task forceClaim(String taskId) - throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException, + throws TaskNotFoundException, + InvalidOwnerException, + NotAuthorizedOnWorkbasketException, InvalidTaskStateException { return claim(taskId, true); } @Override public Task cancelClaim(String taskId) - throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException, + throws TaskNotFoundException, + InvalidOwnerException, + NotAuthorizedOnWorkbasketException, InvalidTaskStateException { - return this.cancelClaim(taskId, false); + return this.cancelClaim(taskId, false, false); } @Override public Task forceCancelClaim(String taskId) throws TaskNotFoundException, InvalidTaskStateException, NotAuthorizedOnWorkbasketException { try { - return this.cancelClaim(taskId, true); + return this.cancelClaim(taskId, true, false); + } catch (InvalidOwnerException e) { + throw new SystemException("this should not have happened. You've discovered a new bug!", e); + } + } + + @Override + public Task cancelClaim(String taskId, boolean keepOwner) + throws TaskNotFoundException, + InvalidOwnerException, + NotAuthorizedOnWorkbasketException, + InvalidTaskStateException { + return this.cancelClaim(taskId, false, keepOwner); + } + + @Override + public Task forceCancelClaim(String taskId, boolean keepOwner) + throws TaskNotFoundException, InvalidTaskStateException, NotAuthorizedOnWorkbasketException { + try { + return this.cancelClaim(taskId, true, keepOwner); } catch (InvalidOwnerException e) { throw new SystemException("this should not have happened. You've discovered a new bug!", e); } @@ -191,51 +216,67 @@ public Task forceCancelClaim(String taskId) @Override public Task requestReview(String taskId) - throws InvalidTaskStateException, TaskNotFoundException, InvalidOwnerException, + throws InvalidTaskStateException, + TaskNotFoundException, + InvalidOwnerException, NotAuthorizedOnWorkbasketException { return requestReview(taskId, false); } @Override public Task forceRequestReview(String taskId) - throws InvalidTaskStateException, TaskNotFoundException, InvalidOwnerException, + throws InvalidTaskStateException, + TaskNotFoundException, + InvalidOwnerException, NotAuthorizedOnWorkbasketException { return requestReview(taskId, true); } @Override public Task requestChanges(String taskId) - throws InvalidTaskStateException, TaskNotFoundException, InvalidOwnerException, + throws InvalidTaskStateException, + TaskNotFoundException, + InvalidOwnerException, NotAuthorizedOnWorkbasketException { return requestChanges(taskId, false); } @Override public Task forceRequestChanges(String taskId) - throws InvalidTaskStateException, TaskNotFoundException, InvalidOwnerException, + throws InvalidTaskStateException, + TaskNotFoundException, + InvalidOwnerException, NotAuthorizedOnWorkbasketException { return requestChanges(taskId, true); } @Override public Task completeTask(String taskId) - throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException, + throws TaskNotFoundException, + InvalidOwnerException, + NotAuthorizedOnWorkbasketException, InvalidTaskStateException { return completeTask(taskId, false); } @Override public Task forceCompleteTask(String taskId) - throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException, + throws TaskNotFoundException, + InvalidOwnerException, + NotAuthorizedOnWorkbasketException, InvalidTaskStateException { return completeTask(taskId, true); } @Override public Task createTask(Task taskToCreate) - throws WorkbasketNotFoundException, ClassificationNotFoundException, - TaskAlreadyExistException, InvalidArgumentException, AttachmentPersistenceException, - ObjectReferencePersistenceException, NotAuthorizedOnWorkbasketException { + throws WorkbasketNotFoundException, + ClassificationNotFoundException, + TaskAlreadyExistException, + InvalidArgumentException, + AttachmentPersistenceException, + ObjectReferencePersistenceException, + NotAuthorizedOnWorkbasketException { if (createTaskPreprocessorManager.isEnabled()) { taskToCreate = createTaskPreprocessorManager.processTaskBeforeCreation(taskToCreate); @@ -417,14 +458,18 @@ public Task getTask(String id) throws NotAuthorizedOnWorkbasketException, TaskNo @Override public Task transfer(String taskId, String destinationWorkbasketId, boolean setTransferFlag) - throws TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedOnWorkbasketException, + throws TaskNotFoundException, + WorkbasketNotFoundException, + NotAuthorizedOnWorkbasketException, InvalidTaskStateException { return taskTransferrer.transfer(taskId, destinationWorkbasketId, setTransferFlag); } @Override public Task transfer(String taskId, String workbasketKey, String domain, boolean setTransferFlag) - throws TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedOnWorkbasketException, + throws TaskNotFoundException, + WorkbasketNotFoundException, + NotAuthorizedOnWorkbasketException, InvalidTaskStateException { return taskTransferrer.transfer(taskId, workbasketKey, domain, setTransferFlag); } @@ -506,9 +551,13 @@ public ObjectReference newObjectReference( @Override public Task updateTask(Task task) - throws InvalidArgumentException, TaskNotFoundException, ConcurrencyException, - AttachmentPersistenceException, ObjectReferencePersistenceException, - ClassificationNotFoundException, NotAuthorizedOnWorkbasketException, + throws InvalidArgumentException, + TaskNotFoundException, + ConcurrencyException, + AttachmentPersistenceException, + ObjectReferencePersistenceException, + ClassificationNotFoundException, + NotAuthorizedOnWorkbasketException, InvalidTaskStateException { String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid(); TaskImpl newTaskImpl = (TaskImpl) task; @@ -563,7 +612,8 @@ public Task updateTask(Task task) @Override public BulkOperationResults transferTasks( String destinationWorkbasketId, List taskIds, boolean setTransferFlag) - throws InvalidArgumentException, WorkbasketNotFoundException, + throws InvalidArgumentException, + WorkbasketNotFoundException, NotAuthorizedOnWorkbasketException { return taskTransferrer.transfer(taskIds, destinationWorkbasketId, setTransferFlag); } @@ -574,7 +624,8 @@ public BulkOperationResults transferTasks( String destinationWorkbasketDomain, List taskIds, boolean setTransferFlag) - throws InvalidArgumentException, WorkbasketNotFoundException, + throws InvalidArgumentException, + WorkbasketNotFoundException, NotAuthorizedOnWorkbasketException { return taskTransferrer.transfer( taskIds, destinationWorkbasketKey, destinationWorkbasketDomain, setTransferFlag); @@ -582,15 +633,21 @@ public BulkOperationResults transferTasks( @Override public void deleteTask(String taskId) - throws TaskNotFoundException, NotAuthorizedException, NotAuthorizedOnWorkbasketException, - InvalidTaskStateException, InvalidCallbackStateException { + throws TaskNotFoundException, + NotAuthorizedException, + NotAuthorizedOnWorkbasketException, + InvalidTaskStateException, + InvalidCallbackStateException { deleteTask(taskId, false); } @Override public void forceDeleteTask(String taskId) - throws TaskNotFoundException, NotAuthorizedException, NotAuthorizedOnWorkbasketException, - InvalidTaskStateException, InvalidCallbackStateException { + throws TaskNotFoundException, + NotAuthorizedException, + NotAuthorizedOnWorkbasketException, + InvalidTaskStateException, + InvalidCallbackStateException { deleteTask(taskId, true); } @@ -759,22 +816,30 @@ public TaskComment createTaskComment(TaskComment taskComment) @Override public TaskComment updateTaskComment(TaskComment taskComment) - throws ConcurrencyException, TaskCommentNotFoundException, TaskNotFoundException, - InvalidArgumentException, NotAuthorizedOnTaskCommentException, + throws ConcurrencyException, + TaskCommentNotFoundException, + TaskNotFoundException, + InvalidArgumentException, + NotAuthorizedOnTaskCommentException, NotAuthorizedOnWorkbasketException { return taskCommentService.updateTaskComment(taskComment); } @Override public void deleteTaskComment(String taskCommentId) - throws TaskCommentNotFoundException, TaskNotFoundException, InvalidArgumentException, - NotAuthorizedOnTaskCommentException, NotAuthorizedOnWorkbasketException { + throws TaskCommentNotFoundException, + TaskNotFoundException, + InvalidArgumentException, + NotAuthorizedOnTaskCommentException, + NotAuthorizedOnWorkbasketException { taskCommentService.deleteTaskComment(taskCommentId); } @Override public TaskComment getTaskComment(String taskCommentid) - throws TaskCommentNotFoundException, TaskNotFoundException, InvalidArgumentException, + throws TaskCommentNotFoundException, + TaskNotFoundException, + InvalidArgumentException, NotAuthorizedOnWorkbasketException { return taskCommentService.getTaskComment(taskCommentid); } @@ -922,7 +987,9 @@ public Task cancelTask(String taskId) @Override public Task terminateTask(String taskId) - throws TaskNotFoundException, NotAuthorizedException, NotAuthorizedOnWorkbasketException, + throws TaskNotFoundException, + NotAuthorizedException, + NotAuthorizedOnWorkbasketException, InvalidTaskStateException { taskanaEngine.getEngine().checkRoleMembership(TaskanaRole.ADMIN, TaskanaRole.TASK_ADMIN); @@ -1265,7 +1332,9 @@ private static void terminateCancelCommonActions(TaskImpl task, TaskState target } private Task claim(String taskId, boolean forceClaim) - throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException, + throws TaskNotFoundException, + InvalidOwnerException, + NotAuthorizedOnWorkbasketException, InvalidTaskStateException { TaskImpl task; try { @@ -1309,7 +1378,9 @@ private Task claim(String taskId, boolean forceClaim) } private Task requestReview(String taskId, boolean force) - throws TaskNotFoundException, InvalidTaskStateException, InvalidOwnerException, + throws TaskNotFoundException, + InvalidTaskStateException, + InvalidOwnerException, NotAuthorizedOnWorkbasketException { String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid(); TaskImpl task; @@ -1360,7 +1431,9 @@ private Task requestReview(String taskId, boolean force) } private Task requestChanges(String taskId, boolean force) - throws InvalidTaskStateException, TaskNotFoundException, InvalidOwnerException, + throws InvalidTaskStateException, + TaskNotFoundException, + InvalidOwnerException, NotAuthorizedOnWorkbasketException { String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid(); TaskImpl task; @@ -1422,9 +1495,12 @@ private static void claimActionsOnTask( } } - private static void cancelClaimActionsOnTask(TaskSummaryImpl task, Instant now) { - task.setOwner(null); - task.setOwnerLongName(null); + private static void cancelClaimActionsOnTask( + TaskSummaryImpl task, Instant now, boolean keepOwner) { + if (!keepOwner) { + task.setOwner(null); + task.setOwnerLongName(null); + } task.setModified(now); task.setClaimed(null); task.setRead(true); @@ -1501,15 +1577,16 @@ private void checkPreconditionsForCompleteTask(TaskSummary task) } } - private Task cancelClaim(String taskId, boolean forceUnclaim) - throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException, + private Task cancelClaim(String taskId, boolean forceUnclaim, boolean keepOwner) + throws TaskNotFoundException, + InvalidOwnerException, + NotAuthorizedOnWorkbasketException, InvalidTaskStateException { String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid(); TaskImpl task; try { taskanaEngine.openConnection(); task = (TaskImpl) getTask(taskId); - TaskImpl oldTask = duplicateTaskExactly(task); TaskState state = task.getState(); @@ -1529,7 +1606,7 @@ private Task cancelClaim(String taskId, boolean forceUnclaim) throw new InvalidOwnerException(userId, taskId); } Instant now = Instant.now(); - cancelClaimActionsOnTask(task, now); + cancelClaimActionsOnTask(task, now, keepOwner); taskMapper.update(task); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Task '{}' unclaimed by user '{}'.", taskId, userId); @@ -1552,7 +1629,9 @@ private Task cancelClaim(String taskId, boolean forceUnclaim) } private Task completeTask(String taskId, boolean isForced) - throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException, + throws TaskNotFoundException, + InvalidOwnerException, + NotAuthorizedOnWorkbasketException, InvalidTaskStateException { String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid(); TaskImpl task; @@ -1596,8 +1675,11 @@ private Task completeTask(String taskId, boolean isForced) } private void deleteTask(String taskId, boolean forceDelete) - throws TaskNotFoundException, NotAuthorizedException, NotAuthorizedOnWorkbasketException, - InvalidTaskStateException, InvalidCallbackStateException { + throws TaskNotFoundException, + NotAuthorizedException, + NotAuthorizedOnWorkbasketException, + InvalidTaskStateException, + InvalidCallbackStateException { taskanaEngine.getEngine().checkRoleMembership(TaskanaRole.ADMIN); TaskImpl task; try { @@ -1751,8 +1833,10 @@ private Optional desiredCallbackStateCanBeSetForFoundSummary( } private void standardSettingsOnTaskCreation(TaskImpl task, Classification classification) - throws InvalidArgumentException, ClassificationNotFoundException, - AttachmentPersistenceException, ObjectReferencePersistenceException { + throws InvalidArgumentException, + ClassificationNotFoundException, + AttachmentPersistenceException, + ObjectReferencePersistenceException { final Instant now = Instant.now(); task.setId(IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_TASK)); if (task.getExternalId() == null) { diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java index a9c5833b99..e373f7c3b9 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java @@ -23,6 +23,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import pro.taskana.classification.api.exceptions.ClassificationNotFoundException; import pro.taskana.common.api.BaseQuery.SortDirection; @@ -288,6 +289,7 @@ public ResponseEntity selectAndClaimTask( * before. * * @param taskId the Id of the requested Task. + * @param keepOwner flag whether or not to keep the owner despite the cancel claim * @return the unclaimed Task. * @throws TaskNotFoundException if the requested Task does not exist. * @throws InvalidTaskStateException if the Task is already in an end state. @@ -298,12 +300,13 @@ public ResponseEntity selectAndClaimTask( */ @DeleteMapping(path = RestEndpoints.URL_TASKS_ID_CLAIM) @Transactional(rollbackFor = Exception.class) - public ResponseEntity cancelClaimTask(@PathVariable String taskId) + public ResponseEntity cancelClaimTask( + @PathVariable String taskId, @RequestParam(defaultValue = "false") boolean keepOwner) throws TaskNotFoundException, InvalidTaskStateException, InvalidOwnerException, NotAuthorizedOnWorkbasketException { - Task updatedTask = taskService.cancelClaim(taskId); + Task updatedTask = taskService.cancelClaim(taskId, keepOwner); return ResponseEntity.ok(taskRepresentationModelAssembler.toModel(updatedTask)); } @@ -312,6 +315,7 @@ public ResponseEntity cancelClaimTask(@PathVariable Str * This endpoint force cancels the claim of an existing Task. * * @param taskId the Id of the requested Task. + * @param keepOwner flag whether or not to keep the owner despite the cancel claim * @return the unclaimed Task. * @throws TaskNotFoundException if the requested Task does not exist. * @throws InvalidTaskStateException if the Task is already in an end state. @@ -322,12 +326,13 @@ public ResponseEntity cancelClaimTask(@PathVariable Str */ @DeleteMapping(path = RestEndpoints.URL_TASKS_ID_CLAIM_FORCE) @Transactional(rollbackFor = Exception.class) - public ResponseEntity forceCancelClaimTask(@PathVariable String taskId) + public ResponseEntity forceCancelClaimTask( + @PathVariable String taskId, @RequestParam(defaultValue = "false") boolean keepOwner) throws TaskNotFoundException, InvalidTaskStateException, InvalidOwnerException, NotAuthorizedOnWorkbasketException { - Task updatedTask = taskService.forceCancelClaim(taskId); + Task updatedTask = taskService.forceCancelClaim(taskId, keepOwner); return ResponseEntity.ok(taskRepresentationModelAssembler.toModel(updatedTask)); } diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java index 00f2454111..3f964d5079 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java @@ -64,16 +64,12 @@ class TaskControllerIntTest { @Autowired TaskanaConfiguration taskanaConfiguration; private static final ParameterizedTypeReference TASK_SUMMARY_PAGE_MODEL_TYPE = new ParameterizedTypeReference<>() {}; - private static final ParameterizedTypeReference TASK_SUMMARY_COLLECTION_MODEL_TYPE = new ParameterizedTypeReference<>() {}; - private static final ParameterizedTypeReference TASK_MODEL_TYPE = ParameterizedTypeReference.forType(TaskRepresentationModel.class); - private final RestHelper restHelper; private final DataSource dataSource; - private final String schemaName; @Autowired @@ -1213,7 +1209,7 @@ void should_ReturnTasksWithVariousOwnerParameters_When_GettingTasks( assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull(); assertThat((response.getBody()).getContent()).hasSize(expectedSize); } - + @TestFactory Stream should_ThrowException_When_OwnerIsNullParamNotStrict() { List> list = @@ -2350,6 +2346,70 @@ void should_CancelClaimTask() { assertThat(cancelClaimedtaskRepresentationModel.getState()).isEqualTo(TaskState.READY); } + @Test + void should_KeepOwnerAndOwnerLongName_When_CancelClaimWithKeepOwner() { + String url = + restHelper.toUrl(RestEndpoints.URL_TASKS_ID, "TKI:000000000000000000000000000000000000"); + HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("user-1-1")); + + // retrieve task from Rest Api + ResponseEntity getTaskResponse = + TEMPLATE.exchange(url, HttpMethod.GET, auth, TASK_MODEL_TYPE); + assertThat(getTaskResponse.getBody()).isNotNull(); + TaskRepresentationModel taskRepresentationModel = getTaskResponse.getBody(); + assertThat(taskRepresentationModel.getState()).isEqualTo(TaskState.CLAIMED); + assertThat(taskRepresentationModel.getOwner()).isEqualTo("user-1-1"); + + // cancel claim + String url2 = + restHelper.toUrl( + RestEndpoints.URL_TASKS_ID_CLAIM + "?keepOwner=true", + "TKI:000000000000000000000000000000000000"); + ResponseEntity cancelClaimResponse = + TEMPLATE.exchange(url2, HttpMethod.DELETE, auth, TASK_MODEL_TYPE); + + assertThat(cancelClaimResponse.getBody()).isNotNull(); + assertThat(cancelClaimResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + TaskRepresentationModel cancelClaimedtaskRepresentationModel = cancelClaimResponse.getBody(); + assertThat(cancelClaimedtaskRepresentationModel.getClaimed()).isNull(); + assertThat(cancelClaimedtaskRepresentationModel.getState()).isEqualTo(TaskState.READY); + assertThat(cancelClaimedtaskRepresentationModel.getOwner()).isEqualTo("user-1-1"); + assertThat(cancelClaimedtaskRepresentationModel.getOwnerLongName()) + .isEqualTo("Mustermann, Max - (user-1-1)"); + } + + @Test + void should_KeepOwnerAndOwnerLongName_When_ForceCancelClaimWithKeepOwner() { + String url = + restHelper.toUrl(RestEndpoints.URL_TASKS_ID, "TKI:000000000000000000000000000000000001"); + HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("user-1-1")); + + // retrieve task from Rest Api + ResponseEntity getTaskResponse = + TEMPLATE.exchange(url, HttpMethod.GET, auth, TASK_MODEL_TYPE); + assertThat(getTaskResponse.getBody()).isNotNull(); + TaskRepresentationModel taskRepresentationModel = getTaskResponse.getBody(); + assertThat(taskRepresentationModel.getState()).isEqualTo(TaskState.CLAIMED); + assertThat(taskRepresentationModel.getOwner()).isEqualTo("user-1-1"); + + // cancel claim + String url2 = + restHelper.toUrl( + RestEndpoints.URL_TASKS_ID_CLAIM_FORCE + "?keepOwner=true", + "TKI:000000000000000000000000000000000001"); + ResponseEntity cancelClaimResponse = + TEMPLATE.exchange(url2, HttpMethod.DELETE, auth, TASK_MODEL_TYPE); + + assertThat(cancelClaimResponse.getBody()).isNotNull(); + assertThat(cancelClaimResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + TaskRepresentationModel cancelClaimedtaskRepresentationModel = cancelClaimResponse.getBody(); + assertThat(cancelClaimedtaskRepresentationModel.getClaimed()).isNull(); + assertThat(cancelClaimedtaskRepresentationModel.getState()).isEqualTo(TaskState.READY); + assertThat(cancelClaimedtaskRepresentationModel.getOwner()).isEqualTo("user-1-1"); + assertThat(cancelClaimedtaskRepresentationModel.getOwnerLongName()) + .isEqualTo("Mustermann, Max - (user-1-1)"); + } + @Test void should_ForceCancelClaim_When_TaskIsClaimedByDifferentOwner() { String url = diff --git a/rest/taskana-rest-spring/src/test/resources/taskana.properties b/rest/taskana-rest-spring/src/test/resources/taskana.properties index af769829ff..3662d285ea 100644 --- a/rest/taskana-rest-spring/src/test/resources/taskana.properties +++ b/rest/taskana-rest-spring/src/test/resources/taskana.properties @@ -30,4 +30,5 @@ taskana.jobs.priority.task.enable=true taskana.jobs.cleanup.workbasket.enable=true taskana.jobs.refresh.user.enable=true taskana.jobs.cleanup.history.simple.enable=false +taskana.user.addAdditionalUserInfo=true