TSK-927 reserve a task via SetOwner

This commit is contained in:
BerndBreier 2020-02-03 13:55:40 +01:00
parent be06d36a96
commit 22ac25f5c9
8 changed files with 370 additions and 155 deletions

View File

@ -250,7 +250,8 @@ public interface TaskService {
*/
Task updateTask(Task task)
throws InvalidArgumentException, TaskNotFoundException, ConcurrencyException,
ClassificationNotFoundException, NotAuthorizedException, AttachmentPersistenceException;
ClassificationNotFoundException, NotAuthorizedException, AttachmentPersistenceException,
InvalidStateException;
/**
* Transfers a list of tasks to an other workbasket. Exceptions will be thrown if the caller got

View File

@ -8,6 +8,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@ -64,6 +65,7 @@ public class TaskServiceImpl implements TaskService {
private static final String IS_ALREADY_CLAIMED_BY = " is already claimed by ";
private static final String IS_ALREADY_COMPLETED = " is already completed.";
private static final String TASK_WITH_ID_IS_NOT_READY = "Task with id %s is not in state ready.";
private static final String WAS_NOT_FOUND2 = " was not found.";
private static final String WAS_NOT_FOUND = " was not found";
private static final String TASK_WITH_ID = "Task with id ";
@ -382,7 +384,8 @@ public class TaskServiceImpl implements TaskService {
@Override
public Task updateTask(Task task)
throws InvalidArgumentException, TaskNotFoundException, ConcurrencyException,
ClassificationNotFoundException, NotAuthorizedException, AttachmentPersistenceException {
ClassificationNotFoundException, NotAuthorizedException, AttachmentPersistenceException,
InvalidStateException {
String userId = CurrentUserContext.getUserid();
LOGGER.debug("entry to updateTask(task = {}, userId = {})", task, userId);
TaskImpl newTaskImpl = (TaskImpl) task;
@ -1537,7 +1540,8 @@ public class TaskServiceImpl implements TaskService {
private void standardUpdateActions(
TaskImpl oldTaskImpl, TaskImpl newTaskImpl, PrioDurationHolder prioDurationFromAttachments)
throws InvalidArgumentException, ConcurrencyException, ClassificationNotFoundException {
throws InvalidArgumentException, ConcurrencyException, ClassificationNotFoundException,
InvalidStateException {
validateObjectReference(newTaskImpl.getPrimaryObjRef(), "primary ObjectReference", "Task");
// TODO: not safe to rely only on different timestamps.
// With fast execution below 1ms there will be no concurrencyException
@ -1571,6 +1575,13 @@ public class TaskServiceImpl implements TaskService {
newTaskImpl.setBusinessProcessId(oldTaskImpl.getBusinessProcessId());
}
// owner can only be changed if task is in state ready
boolean isOwnerChanged = !Objects.equals(newTaskImpl.getOwner(), oldTaskImpl.getOwner());
if (isOwnerChanged && oldTaskImpl.getState() != TaskState.READY) {
throw new InvalidStateException(
String.format(TASK_WITH_ID_IS_NOT_READY, oldTaskImpl.getId()));
}
updateClassificationRelatedProperties(oldTaskImpl, newTaskImpl, prioDurationFromAttachments);
newTaskImpl.setModified(Instant.now());

View File

@ -24,6 +24,7 @@ import pro.taskana.common.api.exceptions.AttachmentPersistenceException;
import pro.taskana.common.api.exceptions.ConcurrencyException;
import pro.taskana.common.api.exceptions.DomainNotFoundException;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.InvalidStateException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.internal.JobServiceImpl;
import pro.taskana.security.JaasExtension;
@ -52,7 +53,8 @@ public class UpdateObjectsUseUtcTimeStampsAccTest extends AbstractAccTest {
@Test
void testTimestampsOnTaskUpdate()
throws TaskNotFoundException, ClassificationNotFoundException, InvalidArgumentException,
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException {
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException,
InvalidStateException {
TaskService taskService = taskanaEngine.getTaskService();
Task task = taskService.getTask("TKI:000000000000000000000000000000000000");
TaskImpl ti = (TaskImpl) task;

View File

@ -32,6 +32,7 @@ import pro.taskana.common.api.TimeInterval;
import pro.taskana.common.api.exceptions.AttachmentPersistenceException;
import pro.taskana.common.api.exceptions.ConcurrencyException;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.InvalidStateException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.internal.TaskanaEngineProxyForTest;
import pro.taskana.security.JaasExtension;
@ -223,7 +224,8 @@ class QueryTasksAccTest extends AbstractAccTest {
@Test
void testQueryForAttachmentInSummary()
throws NotAuthorizedException, InvalidArgumentException, ClassificationNotFoundException,
TaskNotFoundException, ConcurrencyException, AttachmentPersistenceException {
TaskNotFoundException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
TaskService taskService = taskanaEngine.getTaskService();
Attachment attachment =

View File

@ -1,14 +1,7 @@
package acceptance.task;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsNot.not;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import acceptance.AbstractAccTest;
import java.time.Instant;
@ -16,7 +9,6 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -25,6 +17,8 @@ import pro.taskana.classification.api.exceptions.ClassificationNotFoundException
import pro.taskana.common.api.exceptions.AttachmentPersistenceException;
import pro.taskana.common.api.exceptions.ConcurrencyException;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.InvalidOwnerException;
import pro.taskana.common.api.exceptions.InvalidStateException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.security.JaasExtension;
import pro.taskana.security.WithAccessId;
@ -51,7 +45,8 @@ class UpdateTaskAccTest extends AbstractAccTest {
@Test
void testUpdatePrimaryObjectReferenceOfTask()
throws NotAuthorizedException, InvalidArgumentException, ClassificationNotFoundException,
TaskNotFoundException, ConcurrencyException, AttachmentPersistenceException {
TaskNotFoundException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
TaskService taskService = taskanaEngine.getTaskService();
Task task = taskService.getTask("TKI:000000000000000000000000000000000000");
@ -63,16 +58,16 @@ class UpdateTaskAccTest extends AbstractAccTest {
Task updatedTask = taskService.updateTask(task);
updatedTask = taskService.getTask(updatedTask.getId());
assertNotNull(updatedTask);
assertEquals("7654321", updatedTask.getPrimaryObjRef().getValue());
assertNotNull(updatedTask.getCreated());
assertNotNull(updatedTask.getModified());
assertFalse(modifiedOriginal.isAfter(updatedTask.getModified()));
assertNotEquals(updatedTask.getCreated(), updatedTask.getModified());
assertEquals(task.getCreated(), updatedTask.getCreated());
assertEquals(task.isRead(), updatedTask.isRead());
assertEquals("MY_PROCESS_ID", updatedTask.getBusinessProcessId());
assertEquals("MY_PARENT_PROCESS_ID", updatedTask.getParentBusinessProcessId());
assertThat(updatedTask).isNotNull();
assertThat(updatedTask.getPrimaryObjRef().getValue()).isEqualTo("7654321");
assertThat(updatedTask.getCreated()).isNotNull();
assertThat(updatedTask.getModified()).isNotNull();
assertThat(modifiedOriginal.isAfter(updatedTask.getModified())).isFalse();
assertThat(updatedTask.getModified()).isNotEqualTo(updatedTask.getCreated());
assertThat(updatedTask.getCreated()).isEqualTo(task.getCreated());
assertThat(updatedTask.isRead()).isEqualTo(task.isRead());
assertThat(updatedTask.getBusinessProcessId()).isEqualTo("MY_PROCESS_ID");
assertThat(updatedTask.getParentBusinessProcessId()).isEqualTo("MY_PARENT_PROCESS_ID");
}
@WithAccessId(
@ -86,24 +81,30 @@ class UpdateTaskAccTest extends AbstractAccTest {
TaskService taskService = taskanaEngine.getTaskService();
Task task = taskService.getTask("TKI:000000000000000000000000000000000000");
task.setPrimaryObjRef(null);
Assertions.assertThrows(InvalidArgumentException.class, () -> taskService.updateTask(task));
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(InvalidArgumentException.class);
task.setPrimaryObjRef(
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", null));
Assertions.assertThrows(InvalidArgumentException.class, () -> taskService.updateTask(task));
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(InvalidArgumentException.class);
task.setPrimaryObjRef(
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", null, "1234567"));
Assertions.assertThrows(InvalidArgumentException.class, () -> taskService.updateTask(task));
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(InvalidArgumentException.class);
task.setPrimaryObjRef(createObjectReference("COMPANY_A", "SYSTEM_A", null, "VNR", "1234567"));
Assertions.assertThrows(InvalidArgumentException.class, () -> taskService.updateTask(task));
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(InvalidArgumentException.class);
task.setPrimaryObjRef(createObjectReference("COMPANY_A", null, "INSTANCE_A", "VNR", "1234567"));
Assertions.assertThrows(InvalidArgumentException.class, () -> taskService.updateTask(task));
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(InvalidArgumentException.class);
task.setPrimaryObjRef(createObjectReference(null, "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
Assertions.assertThrows(InvalidArgumentException.class, () -> taskService.updateTask(task));
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(InvalidArgumentException.class);
}
@WithAccessId(
@ -112,7 +113,8 @@ class UpdateTaskAccTest extends AbstractAccTest {
@Test
void testThrowsExceptionIfTaskHasAlreadyBeenUpdated()
throws NotAuthorizedException, InvalidArgumentException, ClassificationNotFoundException,
TaskNotFoundException, ConcurrencyException, AttachmentPersistenceException {
TaskNotFoundException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
TaskService taskService = taskanaEngine.getTaskService();
Task task = taskService.getTask("TKI:000000000000000000000000000000000000");
@ -123,10 +125,9 @@ class UpdateTaskAccTest extends AbstractAccTest {
task2.setCustomAttribute("2", "Walter");
// TODO flaky test ... if speed is too high,
Assertions.assertThrows(
ConcurrencyException.class,
() -> taskService.updateTask(task2),
"The task has already been updated by another user");
assertThatThrownBy(() -> taskService.updateTask(task2))
.isInstanceOf(ConcurrencyException.class)
.withFailMessage("The task has already been updated by another user");
}
@WithAccessId(
@ -135,7 +136,8 @@ class UpdateTaskAccTest extends AbstractAccTest {
@Test
void testUpdateClassificationOfTask()
throws TaskNotFoundException, ClassificationNotFoundException, InvalidArgumentException,
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException {
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException,
InvalidStateException {
TaskService taskService = taskanaEngine.getTaskService();
Task task = taskService.getTask("TKI:000000000000000000000000000000000000");
@ -144,13 +146,13 @@ class UpdateTaskAccTest extends AbstractAccTest {
Task updatedTask = taskService.updateTask(task);
updatedTask = taskService.getTask(updatedTask.getId());
assertNotNull(updatedTask);
assertEquals("T2100", updatedTask.getClassificationSummary().getKey());
assertThat(updatedTask.getClassificationSummary(), not(equalTo(classificationSummary)));
assertNotEquals(updatedTask.getCreated(), updatedTask.getModified());
assertEquals(task.getPlanned(), updatedTask.getPlanned());
assertEquals(task.getName(), updatedTask.getName());
assertEquals(task.getDescription(), updatedTask.getDescription());
assertThat(updatedTask).isNotNull();
assertThat(updatedTask.getClassificationSummary().getKey()).isEqualTo("T2100");
assertThat(updatedTask.getClassificationSummary()).isNotEqualTo(classificationSummary);
assertThat(updatedTask.getCreated()).isNotEqualTo(updatedTask.getModified());
assertThat(task.getPlanned()).isEqualTo(updatedTask.getPlanned());
assertThat(task.getName()).isEqualTo(updatedTask.getName());
assertThat(task.getDescription()).isEqualTo(updatedTask.getDescription());
}
@WithAccessId(
@ -163,18 +165,18 @@ class UpdateTaskAccTest extends AbstractAccTest {
taskService.setTaskRead("TKI:000000000000000000000000000000000030", true);
Task updatedTask = taskService.getTask("TKI:000000000000000000000000000000000030");
assertNotNull(updatedTask);
assertTrue(updatedTask.isRead());
assertFalse(updatedTask.getCreated().equals(updatedTask.getModified()));
assertThat(updatedTask).isNotNull();
assertThat(updatedTask.isRead()).isTrue();
assertThat(updatedTask.getCreated()).isNotEqualTo(updatedTask.getModified());
taskService.setTaskRead("TKI:000000000000000000000000000000000030", false);
Task updatedTask2 = taskService.getTask("TKI:000000000000000000000000000000000030");
assertNotNull(updatedTask2);
assertFalse(updatedTask2.isRead());
assertFalse(updatedTask2.getModified().isBefore(updatedTask.getModified()));
assertThat(updatedTask2).isNotNull();
assertThat(updatedTask2.isRead()).isFalse();
assertThat(updatedTask2.getModified().isBefore(updatedTask.getModified())).isFalse();
Assertions.assertThrows(
TaskNotFoundException.class, () -> taskService.setTaskRead("INVALID", true));
assertThatThrownBy(() -> taskService.setTaskRead("INVALID", true))
.isInstanceOf(TaskNotFoundException.class);
}
@WithAccessId(
@ -183,14 +185,15 @@ class UpdateTaskAccTest extends AbstractAccTest {
@Test
void testCustomPropertiesOfTask()
throws TaskNotFoundException, ClassificationNotFoundException, InvalidArgumentException,
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException {
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException,
InvalidStateException {
TaskService taskService = taskanaEngine.getTaskService();
Task task = taskService.getTask("TKI:000000000000000000000000000000000000");
task.setCustomAttribute("1", "T2100");
Task updatedTask = taskService.updateTask(task);
updatedTask = taskService.getTask(updatedTask.getId());
assertNotNull(updatedTask);
assertThat(updatedTask).isNotNull();
}
@WithAccessId(
@ -204,7 +207,8 @@ class UpdateTaskAccTest extends AbstractAccTest {
Task task = taskService.getTask("TKI:000000000000000000000000000000000000");
((TaskImpl) task).setWorkbasketKey("USER_2_2");
Assertions.assertThrows(InvalidArgumentException.class, () -> taskService.updateTask(task));
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(InvalidArgumentException.class);
}
@WithAccessId(
@ -226,7 +230,7 @@ class UpdateTaskAccTest extends AbstractAccTest {
TaskService taskService = taskanaEngine.getTaskService();
List<String> taskIds = taskService.updateTasks(por, customProperties);
assertEquals(0, taskIds.size());
assertThat(taskIds).isEmpty();
}
@WithAccessId(
@ -249,13 +253,13 @@ class UpdateTaskAccTest extends AbstractAccTest {
TaskService taskService = taskanaEngine.getTaskService();
List<String> taskIds = taskService.updateTasks(por, customProperties);
assertEquals(6, taskIds.size());
assertThat(taskIds).hasSize(6);
for (String taskId : taskIds) {
Task task = taskService.getTask(taskId);
assertEquals("This is modifiedValue 3", task.getCustomAttribute("3"));
assertEquals("This is modifiedValue 7", task.getCustomAttribute("7"));
assertEquals("This is modifiedValue 16", task.getCustomAttribute("16"));
assertNull(task.getCustomAttribute("14"));
assertThat(task.getCustomAttribute("3")).isEqualTo("This is modifiedValue 3");
assertThat(task.getCustomAttribute("7")).isEqualTo("This is modifiedValue 7");
assertThat(task.getCustomAttribute("16")).isEqualTo("This is modifiedValue 16");
assertThat(task.getCustomAttribute("14")).isNull();
}
}
@ -278,14 +282,14 @@ class UpdateTaskAccTest extends AbstractAccTest {
TaskService taskService = taskanaEngine.getTaskService();
List<String> changedTasks = taskService.updateTasks(taskIds, customProperties);
assertEquals(3, changedTasks.size());
assertThat(changedTasks).hasSize(3);
for (String taskId : changedTasks) {
Task task = taskService.getTask(taskId);
assertEquals("This is modifiedValue 1", task.getCustomAttribute("1"));
assertEquals("This is modifiedValue 5", task.getCustomAttribute("5"));
assertEquals("This is modifiedValue 10", task.getCustomAttribute("10"));
assertEquals("This is modifiedValue 12", task.getCustomAttribute("12"));
assertNull(task.getCustomAttribute("2"));
assertThat(task.getCustomAttribute("1")).isEqualTo("This is modifiedValue 1");
assertThat(task.getCustomAttribute("5")).isEqualTo("This is modifiedValue 5");
assertThat(task.getCustomAttribute("10")).isEqualTo("This is modifiedValue 10");
assertThat(task.getCustomAttribute("12")).isEqualTo("This is modifiedValue 12");
assertThat(task.getCustomAttribute("2")).isNull();
}
}
@ -296,7 +300,7 @@ class UpdateTaskAccTest extends AbstractAccTest {
void testUpdateCallbackInfoOfSimpleTask()
throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
TaskAlreadyExistException, InvalidArgumentException, TaskNotFoundException,
ConcurrencyException, AttachmentPersistenceException {
ConcurrencyException, AttachmentPersistenceException, InvalidStateException {
TaskService taskService = taskanaEngine.getTaskService();
Task newTask = taskService.newTask("USER_1_1", "DOMAIN_A");
@ -305,20 +309,20 @@ class UpdateTaskAccTest extends AbstractAccTest {
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
Task createdTask = taskService.createTask(newTask);
assertNotNull(createdTask);
assertEquals("1234567", createdTask.getPrimaryObjRef().getValue());
assertNotNull(createdTask.getCreated());
assertNotNull(createdTask.getModified());
assertNotNull(createdTask.getBusinessProcessId());
assertEquals(null, createdTask.getClaimed());
assertEquals(null, createdTask.getCompleted());
assertEquals(createdTask.getCreated(), createdTask.getModified());
assertEquals(createdTask.getCreated(), createdTask.getPlanned());
assertEquals(TaskState.READY, createdTask.getState());
assertEquals(null, createdTask.getParentBusinessProcessId());
assertEquals(2, createdTask.getPriority());
assertEquals(false, createdTask.isRead());
assertEquals(false, createdTask.isTransferred());
assertThat(createdTask).isNotNull();
assertThat(createdTask.getPrimaryObjRef().getValue()).isEqualTo("1234567");
assertThat(createdTask.getCreated()).isNotNull();
assertThat(createdTask.getModified()).isNotNull();
assertThat(createdTask.getBusinessProcessId()).isNotNull();
assertThat(createdTask.getClaimed()).isNull();
assertThat(createdTask.getCompleted()).isNull();
assertThat(createdTask.getModified()).isEqualTo(createdTask.getCreated());
assertThat(createdTask.getPlanned()).isEqualTo(createdTask.getCreated());
assertThat(createdTask.getState()).isEqualTo(TaskState.READY);
assertThat(createdTask.getParentBusinessProcessId()).isNull();
assertThat(createdTask.getPriority()).isEqualTo(2);
assertThat(createdTask.isRead()).isEqualTo(false);
assertThat(createdTask.isTransferred()).isEqualTo(false);
Task retrievedTask = taskService.getTask(createdTask.getId());
@ -331,6 +335,77 @@ class UpdateTaskAccTest extends AbstractAccTest {
Task retrievedUpdatedTask = taskService.getTask(createdTask.getId());
assertEquals(callbackInfo, retrievedUpdatedTask.getCallbackInfo());
assertThat(retrievedUpdatedTask.getCallbackInfo()).isEqualTo(callbackInfo);
}
@WithAccessId(
userName = "user_1_2",
groupNames = {"group_1"})
@Test
void testSetOwnerAndSubsequentClaimSucceeds()
throws TaskNotFoundException, NotAuthorizedException, InvalidStateException,
InvalidOwnerException, ClassificationNotFoundException, InvalidArgumentException,
ConcurrencyException, AttachmentPersistenceException {
TaskService taskService = taskanaEngine.getTaskService();
String taskReadyId = "TKI:000000000000000000000000000000000025";
Task taskReady = taskService.getTask(taskReadyId);
assertThat(taskReady.getState()).isEqualTo(TaskState.READY);
assertThat(taskReady.getOwner()).isNull();
String anyUserName = "Holger";
Task modifiedTaskReady = setOwner(taskReadyId, anyUserName);
assertThat(modifiedTaskReady.getState()).isEqualTo(TaskState.READY);
assertThat(modifiedTaskReady.getOwner()).isEqualTo(anyUserName);
Task taskClaimed = taskService.claim(taskReadyId);
assertThat(taskClaimed.getState()).isEqualTo(TaskState.CLAIMED);
assertThat(taskClaimed.getOwner()).isEqualTo("user_1_2");
}
@WithAccessId(
userName = "user_1_2",
groupNames = {"group_1"})
@Test
void testSetOwnerNotAuthorized()
throws TaskNotFoundException, NotAuthorizedException, InvalidStateException,
InvalidOwnerException {
TaskService taskService = taskanaEngine.getTaskService();
String taskReadyId = "TKI:000000000000000000000000000000000024";
String anyUserName = "Benjamin";
assertThatThrownBy(() -> taskService.getTask(taskReadyId))
.isInstanceOf(NotAuthorizedException.class);
assertThatThrownBy(() -> setOwner(taskReadyId, anyUserName))
.isInstanceOf(NotAuthorizedException.class);
}
@WithAccessId(
userName = "user_1_2",
groupNames = {"group_1"})
@Test
void testSetOwnerOfClaimedTaskFails()
throws TaskNotFoundException, NotAuthorizedException, InvalidStateException,
InvalidOwnerException {
TaskService taskService = taskanaEngine.getTaskService();
String taskClaimedId = "TKI:000000000000000000000000000000000026";
String anyUserName = "Mustapha";
Task taskClaimed = taskService.getTask(taskClaimedId);
assertThat(taskClaimed.getState()).isEqualTo(TaskState.CLAIMED);
assertThat(taskClaimed.getOwner()).isEqualTo("user_1_1");
assertThatThrownBy(() -> setOwner(taskClaimedId, anyUserName))
.isInstanceOf(InvalidStateException.class);
}
private Task setOwner(String taskReadyId, String anyUserName)
throws TaskNotFoundException, NotAuthorizedException, ClassificationNotFoundException,
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
TaskService taskService = taskanaEngine.getTaskService();
Task task = taskService.getTask(taskReadyId);
task.setOwner(anyUserName);
task = taskService.updateTask(task);
return task;
}
}

View File

@ -23,6 +23,7 @@ import pro.taskana.classification.api.exceptions.ClassificationNotFoundException
import pro.taskana.common.api.exceptions.AttachmentPersistenceException;
import pro.taskana.common.api.exceptions.ConcurrencyException;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.InvalidStateException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.internal.security.CurrentUserContext;
import pro.taskana.common.internal.util.DaysToWorkingDaysConverter;
@ -58,7 +59,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
@Test
void testAddNewAttachment()
throws TaskNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException {
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
setUpMethod();
final int attachmentCount = task.getAttachments().size();
assertEquals(1, task.getPriority());
@ -73,8 +75,10 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
task.getAttachments().get(0).getClassificationSummary().getKey(),
equalTo("DOCTYPE_DEFAULT"));
assertThat(
task.getAttachments().get(0).getObjectReference().getCompany(), equalTo("COMPANY_A"));
assertThat(task.getAttachments().get(0).getObjectReference().getSystem(), equalTo("SYSTEM_B"));
task.getAttachments().get(0).getObjectReference().getCompany(),
equalTo("COMPANY_A"));
assertThat(task.getAttachments().get(0).getObjectReference().getSystem(),
equalTo("SYSTEM_B"));
assertThat(
task.getAttachments().get(0).getObjectReference().getSystemInstance(),
equalTo("INSTANCE_B"));
@ -92,7 +96,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
@Test
void testAddValidAttachmentTwice()
throws TaskNotFoundException, ClassificationNotFoundException, InvalidArgumentException,
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException {
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException,
InvalidStateException {
setUpMethod();
task.getAttachments().clear();
task = taskService.updateTask(task);
@ -114,7 +119,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
@Test
void testAddNewAttachmentTwiceWithoutTaskanaMethodWillThrowAttachmentPersistenceException()
throws TaskNotFoundException, ClassificationNotFoundException, InvalidArgumentException,
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException {
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException,
InvalidStateException {
setUpMethod();
final int attachmentCount = 0;
task.getAttachments().clear();
@ -137,7 +143,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
@Test
void testAddExistingAttachmentAgainWillUpdateWhenNotEqual()
throws TaskNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException {
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
setUpMethod();
// Add attachment before
task = taskService.getTask(task.getId());
@ -175,7 +182,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
@Test
void testAddExistingAttachmentAgainWillDoNothingWhenEqual()
throws TaskNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException {
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
setUpMethod();
// Add Attachment before
final int attachmentCount = task.getAttachments().size();
@ -201,7 +209,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
@Test
void testAddAttachmentAsNullValueWillBeIgnored()
throws TaskNotFoundException, ClassificationNotFoundException, InvalidArgumentException,
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException {
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException,
InvalidStateException {
setUpMethod();
// Try to add a single NULL-Element
final int attachmentCount = task.getAttachments().size();
@ -239,7 +248,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
@Test
void testRemoveAttachment()
throws TaskNotFoundException, ClassificationNotFoundException, InvalidArgumentException,
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException {
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException,
InvalidStateException {
setUpMethod();
task.addAttachment(attachment);
task = taskService.updateTask(task);
@ -265,7 +275,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
@Test
void testRemoveAttachmentWithNullAndNotAddedId()
throws TaskNotFoundException, ClassificationNotFoundException, InvalidArgumentException,
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException {
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException,
InvalidStateException {
setUpMethod();
task.addAttachment(attachment);
task = taskService.updateTask(task);
@ -290,7 +301,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
@Test
void testUpdateAttachment()
throws TaskNotFoundException, ClassificationNotFoundException, InvalidArgumentException,
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException {
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException,
InvalidStateException {
setUpMethod();
((TaskImpl) task).setAttachments(new ArrayList<>());
task = taskService.updateTask(task);
@ -330,7 +342,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
@Test
void modifyExistingAttachment()
throws TaskNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException {
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
setUpMethod();
// setup test
assertThat(task.getAttachments().size(), equalTo(0));
@ -426,7 +439,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
@Test
void replaceExistingAttachments()
throws TaskNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException {
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
setUpMethod();
// setup test
assertThat(task.getAttachments().size(), equalTo(0));
@ -491,7 +505,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
void testPrioDurationOfTaskFromAttachmentsAtUpdate()
throws NotAuthorizedException, InvalidArgumentException, ClassificationNotFoundException,
WorkbasketNotFoundException, TaskAlreadyExistException, TaskNotFoundException,
ConcurrencyException, AttachmentPersistenceException {
ConcurrencyException, AttachmentPersistenceException, InvalidStateException {
setUpMethod();
TaskService taskService = taskanaEngine.getTaskService();
@ -556,7 +570,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
@Test
void testAddCustomAttributeToAttachment()
throws TaskNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException {
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
TaskService taskService = taskanaEngine.getTaskService();
task =
@ -593,7 +608,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
// the begin of each testcase....
private void setUpMethod()
throws TaskNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException {
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
taskService = taskanaEngine.getTaskService();
task =
taskService.getTask(

View File

@ -228,7 +228,8 @@ public class TaskController extends AbstractPagingController {
public ResponseEntity<TaskResource> updateTask(
@PathVariable(value = "taskId") String taskId, @RequestBody TaskResource taskResource)
throws TaskNotFoundException, ClassificationNotFoundException, InvalidArgumentException,
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException {
ConcurrencyException, NotAuthorizedException, AttachmentPersistenceException,
InvalidStateException {
LOGGER.debug("Entry to updateTask(taskId= {}, taskResource= {})", taskId, taskResource);
ResponseEntity<TaskResource> result;
if (taskId.equals(taskResource.getTaskId())) {

View File

@ -2,10 +2,12 @@ package pro.taskana.rest;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
@ -17,7 +19,6 @@ import java.time.Instant;
import java.time.temporal.ChronoUnit;
import javax.sql.DataSource;
import org.assertj.core.api.Fail;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@ -40,6 +41,9 @@ import pro.taskana.rest.resource.TaskSummaryListResource;
import pro.taskana.rest.resource.WorkbasketSummaryResource;
import pro.taskana.sampledata.SampleDataGenerator;
import pro.taskana.task.api.ObjectReference;
import pro.taskana.task.api.TaskState;
// import org.junit.jupiter.api.Assertions;
/** Test Task Controller. */
@TaskanaSpringBootTest
@ -161,22 +165,21 @@ class TaskControllerIntTest {
@Test
void testGetAllTasksByWorkbasketIdWithInvalidPlannedParamsCombination() {
HttpClientErrorException e =
Assertions.assertThrows(
HttpClientErrorException.class,
() ->
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS)
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
+ "&planned=2020-01-22T09:44:47.453Z,,"
+ "2020-01-19T07:44:47.453Z,2020-01-19T19:44:47.453Z,"
+ ",2020-01-18T09:44:47.453Z"
+ "&planned-from=2020-01-19T07:44:47.453Z"
+ "&sort-by=planned",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(TaskSummaryListResource.class)));
assertThat(HttpStatus.BAD_REQUEST).isEqualTo(e.getStatusCode());
assertThatThrownBy(
() ->
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS)
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
+ "&planned=2020-01-22T09:44:47.453Z,,"
+ "2020-01-19T07:44:47.453Z,2020-01-19T19:44:47.453Z,"
+ ",2020-01-18T09:44:47.453Z"
+ "&planned-from=2020-01-19T07:44:47.453Z"
+ "&sort-by=planned",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(TaskSummaryListResource.class)))
.isInstanceOf(HttpClientErrorException.class)
.hasMessageContaining("400");
}
@Test
@ -251,22 +254,21 @@ class TaskControllerIntTest {
@Test
void testGetAllTasksByWorkbasketIdWithInvalidDueParamsCombination() {
HttpClientErrorException e =
Assertions.assertThrows(
HttpClientErrorException.class,
() ->
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS)
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
+ "&due=2020-01-22T09:44:47.453Z,,"
+ "2020-01-19T07:44:47.453Z,2020-01-19T19:44:47.453Z,"
+ ",2020-01-18T09:44:47.453Z"
+ "&due-from=2020-01-19T07:44:47.453Z"
+ "&sort-by=planned",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(TaskSummaryListResource.class)));
assertThat(HttpStatus.BAD_REQUEST).isEqualTo(e.getStatusCode());
assertThatThrownBy(
() ->
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS)
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
+ "&due=2020-01-22T09:44:47.453Z,,"
+ "2020-01-19T07:44:47.453Z,2020-01-19T19:44:47.453Z,"
+ ",2020-01-18T09:44:47.453Z"
+ "&due-from=2020-01-19T07:44:47.453Z"
+ "&sort-by=planned",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(TaskSummaryListResource.class)))
.isInstanceOf(HttpClientErrorException.class)
.hasMessageContaining("400");
}
@Test
@ -291,18 +293,17 @@ class TaskControllerIntTest {
headers.add("Authorization", "Basic dXNlcl8xXzI6dXNlcl8xXzI="); // user_1_2
HttpEntity<String> request = new HttpEntity<String>(headers);
HttpClientErrorException e =
Assertions.assertThrows(
HttpClientErrorException.class,
() -> {
ResponseEntity<TaskSummaryListResource> response =
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS) + "?workbasket-key=USER_1_2",
HttpMethod.GET,
request,
ParameterizedTypeReference.forType(TaskSummaryListResource.class));
});
assertThat(HttpStatus.BAD_REQUEST).isEqualTo(e.getStatusCode());
assertThatThrownBy(
() -> {
ResponseEntity<TaskSummaryListResource> response =
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS) + "?workbasket-key=USER_1_2",
HttpMethod.GET,
request,
ParameterizedTypeReference.forType(TaskSummaryListResource.class));
})
.isInstanceOf(HttpClientErrorException.class)
.hasMessageContaining("400");
}
@Test
@ -585,14 +586,14 @@ class TaskControllerIntTest {
taskResource.setPlanned(now.toString());
taskResource.setDue(now.toString());
Assertions.assertThrows(
HttpClientErrorException.class,
() ->
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS),
HttpMethod.POST,
new HttpEntity<>(taskResource, restHelper.getHeaders()),
ParameterizedTypeReference.forType(TaskResource.class)));
assertThatThrownBy(
() ->
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS),
HttpMethod.POST,
new HttpEntity<>(taskResource, restHelper.getHeaders()),
ParameterizedTypeReference.forType(TaskResource.class)))
.isInstanceOf(HttpClientErrorException.class);
}
@Test
@ -617,7 +618,6 @@ class TaskControllerIntTest {
assertThat(con.getResponseCode()).isEqualTo(400);
con.disconnect();
final String taskToCreateJson2 =
"{\"classificationSummaryResource\":"
+ "{\"classificationId\":\"CLI:100000000000000000000000000000000004\"},"
@ -640,6 +640,113 @@ class TaskControllerIntTest {
con.disconnect();
}
@Test
void testUpdateTaskOwnerOfReadyTaskSucceeds() throws IOException {
URL url = new URL(restHelper.toUrl("/api/v1/tasks/TKI:000000000000000000000000000000000025"));
// retrieve task from Rest Api
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Authorization", "Basic dXNlcl8xXzI6dXNlcl8xXzI="); // user_1_2
assertThat(con.getResponseCode()).isEqualTo(200);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream(), UTF_8));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
con.disconnect();
final String originalTaskJson = content.toString();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
TaskResource originalTaskObject = mapper.readValue(originalTaskJson, TaskResource.class);
String originalOwner = originalTaskObject.getOwner();
assertThat(originalOwner == null);
// set owner and call updateTask on Rest Api
final String anyUserName = "Benjamin";
TaskResource taskObjectWithUpdatedOwner = originalTaskObject;
taskObjectWithUpdatedOwner.setOwner(anyUserName);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("PUT");
con.setDoOutput(true);
con.setRequestProperty("Authorization", "Basic dXNlcl8xXzI6dXNlcl8xXzI=");
con.setRequestProperty("Content-Type", "application/json");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(con.getOutputStream(), UTF_8));
final String taskWithUpdatedOwnerJson = mapper.writeValueAsString(taskObjectWithUpdatedOwner);
out.write(taskWithUpdatedOwnerJson);
out.flush();
out.close();
assertThat(con.getResponseCode()).isEqualTo(200);
con.disconnect();
// retrieve task once again from Rest Api.
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Authorization", "Basic dXNlcl8xXzI6dXNlcl8xXzI=");
assertThat(con.getResponseCode()).isEqualTo(200);
in = new BufferedReader(new InputStreamReader(con.getInputStream(), UTF_8));
content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
con.disconnect();
final String retrievedTaskJson = content.toString();
TaskResource retrievedTaskObject = mapper.readValue(retrievedTaskJson, TaskResource.class);
assertThat(retrievedTaskObject.getOwner()).isEqualTo(anyUserName);
}
@Test
void testUpdateTaskOwnerOfClaimedTaskFails() throws IOException {
URL url = new URL(restHelper.toUrl("/api/v1/tasks/TKI:000000000000000000000000000000000026"));
// retrieve task from Rest Api
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Authorization", "Basic dXNlcl8xXzI6dXNlcl8xXzI="); // user_1_2
assertThat(con.getResponseCode()).isEqualTo(200);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream(), UTF_8));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
con.disconnect();
final String originalTaskJson = content.toString();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
TaskResource originalTaskObject = mapper.readValue(originalTaskJson, TaskResource.class);
String originalOwner = originalTaskObject.getOwner();
assertThat(originalTaskObject.getOwner()).isEqualTo("user_1_1");
assertThat(originalTaskObject.getState()).isEqualTo(TaskState.CLAIMED);
// set owner and call updateTask on Rest Api
final String anyUserName = "Mustapha";
TaskResource taskObjectWithUpdatedOwner = originalTaskObject;
taskObjectWithUpdatedOwner.setOwner(anyUserName);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("PUT");
con.setDoOutput(true);
con.setRequestProperty("Authorization", "Basic dXNlcl8xXzI6dXNlcl8xXzI=");
con.setRequestProperty("Content-Type", "application/json");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(con.getOutputStream(), UTF_8));
final String taskWithUpdatedOwnerJson = mapper.writeValueAsString(taskObjectWithUpdatedOwner);
out.write(taskWithUpdatedOwnerJson);
out.flush();
out.close();
assertThat(con.getResponseCode()).isEqualTo(409);
con.disconnect();
}
private TaskResource getTaskResourceSample() {
ClassificationSummaryResource classificationResource = new ClassificationSummaryResource();
classificationResource.key = "L11010";