From b6a75ed5e7005f99a78c1cce550dbb3c2e852bf6 Mon Sep 17 00:00:00 2001 From: Marcel Lengl <52546181+LenglBoy@users.noreply.github.com> Date: Tue, 19 Dec 2017 13:17:58 +0100 Subject: [PATCH] TSK-87: Transfer Task, improved Integration-Tests, Updated CreateTask() with AlreadyExistException --- lib/.gitignore | 3 + .../java/pro/taskana/ExampleBootstrap.java | 33 ++- .../src/test/java/pro/taskana/TaskanaEjb.java | 44 +-- .../java/pro/taskana/TaskanaRestTest.java | 73 ++--- .../main/java/pro/taskana/TaskService.java | 9 +- .../exceptions/TaskAlreadyExistException.java | 14 + .../pro/taskana/impl/TaskServiceImpl.java | 15 +- .../pro/taskana/impl/TaskServiceImplTest.java | 104 +++++-- .../TaskServiceImplIntAutocommitTest.java | 181 +++++++++++- .../TaskServiceImplIntExplicitTest.java | 268 ++++++++++++++++-- .../java/pro/taskana/ExampleBootstrap.java | 34 +-- .../java/pro/taskana/TaskanaComponent.java | 26 +- 12 files changed, 644 insertions(+), 160 deletions(-) create mode 100644 lib/taskana-core/src/main/java/pro/taskana/exceptions/TaskAlreadyExistException.java diff --git a/lib/.gitignore b/lib/.gitignore index 3c07b903b..622aa9700 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -23,3 +23,6 @@ nbbuild/ dist/ nbdist/ .nb-gradle/ + +### DEV-TOOLS ### +.checkstyle \ No newline at end of file diff --git a/lib/taskana-cdi-example/src/main/java/pro/taskana/ExampleBootstrap.java b/lib/taskana-cdi-example/src/main/java/pro/taskana/ExampleBootstrap.java index c8bb7498f..d204a0db5 100644 --- a/lib/taskana-cdi-example/src/main/java/pro/taskana/ExampleBootstrap.java +++ b/lib/taskana-cdi-example/src/main/java/pro/taskana/ExampleBootstrap.java @@ -10,26 +10,29 @@ import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.exceptions.InvalidOwnerException; import pro.taskana.exceptions.InvalidStateException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.TaskNotFoundException; import pro.taskana.exceptions.WorkbasketNotFoundException; @ApplicationScoped public class ExampleBootstrap { - @EJB - private TaskanaEjb taskanaEjb; + @EJB + private TaskanaEjb taskanaEjb; - @PostConstruct - public void init(@Observes @Initialized(ApplicationScoped.class) Object init) throws TaskNotFoundException, NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, InvalidStateException, InvalidOwnerException { - System.out.println("---------------------------> Start App"); - Task task = taskanaEjb.getTaskService().newTask(); - task = taskanaEjb.getTaskService().createTask(task); - System.out.println("---------------------------> Task started: " + task.getId()); - taskanaEjb.getTaskService().claim(task.getId()); - System.out.println( - "---------------------------> Task claimed: " - + taskanaEjb.getTaskService().getTaskById(task.getId()).getOwner()); - taskanaEjb.getTaskService().completeTask(task.getId()); - System.out.println("---------------------------> Task completed"); - } + @PostConstruct + public void init(@Observes @Initialized(ApplicationScoped.class) Object init) + throws TaskNotFoundException, NotAuthorizedException, WorkbasketNotFoundException, + ClassificationNotFoundException, InvalidStateException, InvalidOwnerException, TaskAlreadyExistException { + System.out.println("---------------------------> Start App"); + Task task = taskanaEjb.getTaskService().newTask(); + task = taskanaEjb.getTaskService().createTask(task); + System.out.println("---------------------------> Task started: " + task.getId()); + taskanaEjb.getTaskService().claim(task.getId()); + System.out.println( + "---------------------------> Task claimed: " + + taskanaEjb.getTaskService().getTaskById(task.getId()).getOwner()); + taskanaEjb.getTaskService().completeTask(task.getId()); + System.out.println("---------------------------> Task completed"); + } } diff --git a/lib/taskana-cdi/src/test/java/pro/taskana/TaskanaEjb.java b/lib/taskana-cdi/src/test/java/pro/taskana/TaskanaEjb.java index 9d2d610cd..aa7db4aba 100644 --- a/lib/taskana-cdi/src/test/java/pro/taskana/TaskanaEjb.java +++ b/lib/taskana-cdi/src/test/java/pro/taskana/TaskanaEjb.java @@ -5,37 +5,39 @@ import javax.inject.Inject; import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.WorkbasketNotFoundException; @Stateless public class TaskanaEjb { - @Inject - private TaskService taskService; + @Inject + private TaskService taskService; - @Inject - private ClassificationService classificationService; + @Inject + private ClassificationService classificationService; - @Inject - private WorkbasketService workbasketService; + @Inject + private WorkbasketService workbasketService; - public TaskService getTaskService() { - return taskService; - } + public TaskService getTaskService() { + return taskService; + } - public ClassificationService getClassificationService() { - return classificationService; - } + public ClassificationService getClassificationService() { + return classificationService; + } - public WorkbasketService getWorkbasketService() { - return workbasketService; - } + public WorkbasketService getWorkbasketService() { + return workbasketService; + } - public void triggerRollback() throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException { - Task task = taskService.newTask(); - taskService.createTask(task); - System.out.println("---------------->" + task.getId()); - throw new RuntimeException(); - } + public void triggerRollback() throws NotAuthorizedException, WorkbasketNotFoundException, + ClassificationNotFoundException, TaskAlreadyExistException { + Task task = taskService.newTask(); + taskService.createTask(task); + System.out.println("---------------->" + task.getId()); + throw new RuntimeException(); + } } diff --git a/lib/taskana-cdi/src/test/java/pro/taskana/TaskanaRestTest.java b/lib/taskana-cdi/src/test/java/pro/taskana/TaskanaRestTest.java index 4bed5f814..c02be8d3a 100644 --- a/lib/taskana-cdi/src/test/java/pro/taskana/TaskanaRestTest.java +++ b/lib/taskana-cdi/src/test/java/pro/taskana/TaskanaRestTest.java @@ -17,52 +17,55 @@ import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.exceptions.InvalidOwnerException; import pro.taskana.exceptions.InvalidStateException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.TaskNotFoundException; import pro.taskana.exceptions.WorkbasketNotFoundException; -import pro.taskana.Workbasket; -import pro.taskana.Task; @Path("/test") public class TaskanaRestTest { - private static final Logger logger = LoggerFactory.getLogger(TaskanaRestTest.class); + private static final Logger logger = LoggerFactory.getLogger(TaskanaRestTest.class); - @EJB - private TaskanaEjb taskanaEjb; - - @Inject - private ClassificationService classificationService; + @EJB + private TaskanaEjb taskanaEjb; - @GET - public Response startTask() throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException { - Workbasket workbasket = taskanaEjb.getWorkbasketService().newWorkbasket();; - workbasket.setName("wb"); - taskanaEjb.getWorkbasketService().createWorkbasket(workbasket); - Classification classification = classificationService.newClassification(); - classification.setKey("TEST"); - taskanaEjb.getClassificationService().createClassification(classification); + @Inject + private ClassificationService classificationService; - Task task = taskanaEjb.getTaskService().newTask(); - task.setClassification(classification); - task.setWorkbasketId(workbasket.getId()); + @GET + public Response startTask() throws NotAuthorizedException, WorkbasketNotFoundException, + ClassificationNotFoundException, ClassificationAlreadyExistException, TaskAlreadyExistException { + Workbasket workbasket = taskanaEjb.getWorkbasketService().newWorkbasket(); + ; + workbasket.setName("wb"); + taskanaEjb.getWorkbasketService().createWorkbasket(workbasket); + Classification classification = classificationService.newClassification(); + classification.setKey("TEST"); + taskanaEjb.getClassificationService().createClassification(classification); - Task resultTask = taskanaEjb.getTaskService().createTask(task); + Task task = taskanaEjb.getTaskService().newTask(); + task.setClassification(classification); + task.setWorkbasketId(workbasket.getId()); - logger.info(resultTask.getId() + ":" + resultTask.getOwner()); - return Response.status(200).entity(resultTask.getId()).build(); - } - - @POST - public Response rollbackTask() throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException { - taskanaEjb.triggerRollback(); - return Response.status(204).build(); - } + Task resultTask = taskanaEjb.getTaskService().createTask(task); - @DELETE - @Path("{id}") - public void completeTask(@PathParam("id") String id) throws TaskNotFoundException, InvalidOwnerException, InvalidStateException { - logger.info(id); - taskanaEjb.getTaskService().completeTask(id, true); - } + logger.info(resultTask.getId() + ":" + resultTask.getOwner()); + return Response.status(200).entity(resultTask.getId()).build(); + } + + @POST + public Response rollbackTask() throws NotAuthorizedException, WorkbasketNotFoundException, + ClassificationNotFoundException, TaskAlreadyExistException { + taskanaEjb.triggerRollback(); + return Response.status(204).build(); + } + + @DELETE + @Path("{id}") + public void completeTask(@PathParam("id") String id) + throws TaskNotFoundException, InvalidOwnerException, InvalidStateException { + logger.info(id); + taskanaEjb.getTaskService().completeTask(id, true); + } } diff --git a/lib/taskana-core/src/main/java/pro/taskana/TaskService.java b/lib/taskana-core/src/main/java/pro/taskana/TaskService.java index 60c24ebaa..1db49d126 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/TaskService.java +++ b/lib/taskana-core/src/main/java/pro/taskana/TaskService.java @@ -6,6 +6,7 @@ import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.exceptions.InvalidOwnerException; import pro.taskana.exceptions.InvalidStateException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.TaskNotFoundException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.model.TaskState; @@ -83,11 +84,13 @@ public interface TaskService { throws TaskNotFoundException, InvalidOwnerException, InvalidStateException; /** - * Create and persist a task. + * Persists a not persisted Task which does not exist already. * * @param taskToCreate * the transient task object to be persisted * @return the created and persisted task + * @throws TaskAlreadyExistException + * when the Task does already exist. * @throws NotAuthorizedException * thrown if the current user is not authorized to create that task * @throws WorkbasketNotFoundException @@ -96,7 +99,8 @@ public interface TaskService { * thrown if the {@link Classification} referenced by the task is not found */ Task createTask(Task taskToCreate) - throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException; + throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, + TaskAlreadyExistException; /** * Get the details of a task by Id. @@ -176,6 +180,7 @@ public interface TaskService { /** * Returns a not persisted instance of {@link Task}. + * * @return task - with default values */ Task newTask(); diff --git a/lib/taskana-core/src/main/java/pro/taskana/exceptions/TaskAlreadyExistException.java b/lib/taskana-core/src/main/java/pro/taskana/exceptions/TaskAlreadyExistException.java new file mode 100644 index 000000000..c151d34fa --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/exceptions/TaskAlreadyExistException.java @@ -0,0 +1,14 @@ +package pro.taskana.exceptions; + +/** + * Thrown when a Task is going to be created, but a Task with the same ID does already exist. The Task ID should be + * unique. + */ +public class TaskAlreadyExistException extends TaskanaException { + + public TaskAlreadyExistException(String id) { + super(id); + } + + private static final long serialVersionUID = 1L; +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java index 33b6c57e3..6fd28b969 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java @@ -19,6 +19,7 @@ import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.exceptions.InvalidOwnerException; import pro.taskana.exceptions.InvalidStateException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.TaskNotFoundException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.impl.util.IdGenerator; @@ -153,10 +154,17 @@ public class TaskServiceImpl implements TaskService { @Override public Task createTask(Task taskToCreate) - throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException { + throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, + TaskAlreadyExistException { LOGGER.debug("entry to createTask(task = {})", taskToCreate); try { taskanaEngineImpl.openConnection(); + try { + this.getTaskById(taskToCreate.getId()); + throw new TaskAlreadyExistException(taskToCreate.getId()); + } catch (TaskNotFoundException ex) { + LOGGER.debug("Task {} can“t be be found, so it can be created.", taskToCreate.getId()); + } TaskImpl task = (TaskImpl) taskToCreate; workbasketService.getWorkbasket(task.getWorkbasketId()); workbasketService.checkAuthorization(task.getWorkbasketId(), WorkbasketAuthorization.APPEND); @@ -164,7 +172,8 @@ public class TaskServiceImpl implements TaskService { if (classification == null) { throw new ClassificationNotFoundException(null); } - taskanaEngine.getClassificationService().getClassification(classification.getKey(), classification.getDomain()); + taskanaEngine.getClassificationService().getClassification(classification.getKey(), + classification.getDomain()); standardSettings(task); @@ -269,7 +278,7 @@ public class TaskServiceImpl implements TaskService { taskanaEngineImpl.openConnection(); workbasketService.checkAuthorization(workbasketId, WorkbasketAuthorization.READ); List tasks = taskMapper.findTasksByWorkbasketIdAndState(workbasketId, taskState); - tasks.stream().forEach(t -> results.add((Task) t)); + tasks.stream().forEach(t -> results.add(t)); } finally { taskanaEngineImpl.returnConnection(); if (LOGGER.isDebugEnabled()) { diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/TaskServiceImplTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/TaskServiceImplTest.java index 3243d4923..deb4b7bda 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/TaskServiceImplTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/TaskServiceImplTest.java @@ -41,6 +41,7 @@ import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.exceptions.InvalidOwnerException; import pro.taskana.exceptions.InvalidStateException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.TaskNotFoundException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.model.ClassificationImpl; @@ -105,18 +106,21 @@ public class TaskServiceImplTest { @Test public void testCreateSimpleTask() throws NotAuthorizedException, WorkbasketNotFoundException, - ClassificationNotFoundException, ClassificationAlreadyExistException { - Mockito.doNothing().when(taskMapperMock).insert(any()); + ClassificationNotFoundException, ClassificationAlreadyExistException, TaskAlreadyExistException, + TaskNotFoundException { + TaskServiceImpl cutSpy = Mockito.spy(cut); TaskImpl expectedTask = createUnitTestTask("1", "DUMMYTASK", "1"); WorkbasketImpl wb = new WorkbasketImpl(); wb.setId("1"); wb.setName("workbasket"); + doThrow(TaskNotFoundException.class).when(cutSpy).getTaskById(expectedTask.getId()); doReturn(wb).when(workbasketServiceMock).getWorkbasket(wb.getId()); - doNothing().when(taskMapperMock).insert(any()); + doNothing().when(taskMapperMock).insert(expectedTask); - Task actualTask = cut.createTask(expectedTask); + Task actualTask = cutSpy.createTask(expectedTask); verify(taskanaEngineImpl, times(1)).openConnection(); + verify(cutSpy, times(1)).getTaskById(any()); verify(workbasketServiceMock, times(1)).checkAuthorization(any(), any()); verify(workbasketServiceMock, times(1)).getWorkbasket(any()); verify(taskanaEngineMock, times(1)).getClassificationService(); @@ -138,7 +142,9 @@ public class TaskServiceImplTest { @Test public void testCreateSimpleTaskWithObjectReference() throws NotAuthorizedException, WorkbasketNotFoundException, - ClassificationNotFoundException, ClassificationAlreadyExistException { + ClassificationNotFoundException, ClassificationAlreadyExistException, TaskAlreadyExistException, + TaskNotFoundException { + TaskServiceImpl cutSpy = Mockito.spy(cut); ObjectReference expectedObjectReference = new ObjectReference(); expectedObjectReference.setId("1"); expectedObjectReference.setType("DUMMY"); @@ -148,17 +154,21 @@ public class TaskServiceImplTest { TaskImpl expectedTask = createUnitTestTask("1", "DUMMYTASK", wb.getId()); expectedTask.setPrimaryObjRef(expectedObjectReference); Classification classification = expectedTask.getClassification(); + doThrow(TaskNotFoundException.class).when(cutSpy).getTaskById(expectedTask.getId()); doReturn(wb).when(workbasketServiceMock).getWorkbasket(wb.getId()); - doReturn(expectedObjectReference).when(objectReferenceMapperMock).findByObjectReference(expectedObjectReference); + doReturn(expectedObjectReference).when(objectReferenceMapperMock) + .findByObjectReference(expectedObjectReference); doNothing().when(taskMapperMock).insert(expectedTask); - Task actualTask = cut.createTask(expectedTask); + Task actualTask = cutSpy.createTask(expectedTask); verify(taskanaEngineImpl, times(1)).openConnection(); + verify(cutSpy, times(1)).getTaskById(any()); verify(workbasketServiceMock, times(1)).getWorkbasket(wb.getId()); verify(workbasketServiceMock, times(1)).checkAuthorization(wb.getId(), WorkbasketAuthorization.APPEND); verify(taskanaEngineMock, times(1)).getClassificationService(); - verify(classificationServiceMock, times(1)).getClassification(classification.getKey(), classification.getDomain()); + verify(classificationServiceMock, times(1)).getClassification(classification.getKey(), + classification.getDomain()); verify(objectReferenceMapperMock, times(1)).findByObjectReference(expectedObjectReference); verify(taskMapperMock, times(1)).insert(expectedTask); verify(taskanaEngineImpl, times(1)).returnConnection(); @@ -177,7 +187,9 @@ public class TaskServiceImplTest { @Test public void testCreateSimpleTaskWithObjectReferenceIsNull() throws NotAuthorizedException, - WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException { + WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException, + TaskAlreadyExistException, TaskNotFoundException { + TaskServiceImpl cutSpy = Mockito.spy(cut); ObjectReference expectedObjectReference = new ObjectReference(); expectedObjectReference.setId("1"); expectedObjectReference.setType("DUMMY"); @@ -188,19 +200,24 @@ public class TaskServiceImplTest { TaskImpl expectedTask = createUnitTestTask("1", "DUMMYTASK", "1"); expectedTask.setPrimaryObjRef(expectedObjectReference); Classification classification = expectedTask.getClassification(); - doReturn(classification).when(classificationServiceMock).getClassification(classification.getKey(), classification.getDomain()); + doThrow(TaskNotFoundException.class).when(cutSpy).getTaskById(expectedTask.getId()); + doReturn(classification).when(classificationServiceMock).getClassification(classification.getKey(), + classification.getDomain()); doNothing().when(taskMapperMock).insert(expectedTask); doNothing().when(objectReferenceMapperMock).insert(expectedObjectReference); doReturn(null).when(objectReferenceMapperMock).findByObjectReference(expectedTask.getPrimaryObjRef()); - Task actualTask = cut.createTask(expectedTask); + Task actualTask = cutSpy.createTask(expectedTask); expectedTask.getPrimaryObjRef().setId(actualTask.getPrimaryObjRef().getId()); // get only new ID verify(taskanaEngineImpl, times(1)).openConnection(); + verify(cutSpy, times(1)).getTaskById(any()); verify(workbasketServiceMock, times(1)).getWorkbasket(expectedTask.getWorkbasketId()); - verify(workbasketServiceMock, times(1)).checkAuthorization(expectedTask.getWorkbasketId(), WorkbasketAuthorization.APPEND); + verify(workbasketServiceMock, times(1)).checkAuthorization(expectedTask.getWorkbasketId(), + WorkbasketAuthorization.APPEND); verify(taskanaEngineMock, times(1)).getClassificationService(); - verify(classificationServiceMock, times(1)).getClassification(classification.getKey(), classification.getDomain()); + verify(classificationServiceMock, times(1)).getClassification(classification.getKey(), + classification.getDomain()); verify(objectReferenceMapperMock, times(1)).findByObjectReference(expectedObjectReference); verify(objectReferenceMapperMock, times(1)).insert(expectedObjectReference); verify(taskMapperMock, times(1)).insert(expectedTask); @@ -220,11 +237,13 @@ public class TaskServiceImplTest { @Test public void testCreateTaskWithPlanned() - throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException { + throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, + TaskAlreadyExistException, TaskNotFoundException { + TaskServiceImpl cutSpy = Mockito.spy(cut); ObjectReference expectedObjectReference = new ObjectReference(); expectedObjectReference.setId("1"); expectedObjectReference.setType("DUMMY"); - Classification classification = (Classification) new ClassificationImpl(); + Classification classification = new ClassificationImpl(); classification.setName("Name"); classification.setCategory("MANUAL"); WorkbasketImpl wb = new WorkbasketImpl(); @@ -235,12 +254,15 @@ public class TaskServiceImplTest { task.setClassification(classification); task.setPrimaryObjRef(expectedObjectReference); task.setDescription("simply awesome task"); + doThrow(TaskNotFoundException.class).when(cutSpy).getTaskById(task.getId()); doReturn(wb).when(workbasketServiceMock).getWorkbasket(wb.getId()); - doReturn(classification).when(classificationServiceMock).getClassification(classification.getKey(), classification.getDomain()); - doReturn(expectedObjectReference).when(objectReferenceMapperMock).findByObjectReference(expectedObjectReference); + doReturn(classification).when(classificationServiceMock).getClassification(classification.getKey(), + classification.getDomain()); + doReturn(expectedObjectReference).when(objectReferenceMapperMock) + .findByObjectReference(expectedObjectReference); doNothing().when(taskMapperMock).insert(task); - cut.createTask(task); + cutSpy.createTask(task); TaskImpl task2 = new TaskImpl(); task2.setWorkbasketId(wb.getId()); @@ -249,9 +271,10 @@ public class TaskServiceImplTest { task2.setPlanned(Timestamp.valueOf(LocalDateTime.now().minusHours(1))); task2.setName("Task2"); - cut.createTask(task2); + cutSpy.createTask(task2); verify(taskanaEngineImpl, times(2)).openConnection(); + verify(cutSpy, times(2)).getTaskById(any()); verify(workbasketServiceMock, times(2)).checkAuthorization(any(), any()); verify(workbasketServiceMock, times(2)).getWorkbasket(any()); verify(taskanaEngineMock, times(2)).getClassificationService(); @@ -278,17 +301,43 @@ public class TaskServiceImplTest { assertThat(task2.getPlanned(), not(task2.getCreated())); } + @Test(expected = TaskAlreadyExistException.class) + public void testCreateTaskThrowingAlreadyExistException() throws WorkbasketNotFoundException, + ClassificationNotFoundException, NotAuthorizedException, TaskAlreadyExistException, TaskNotFoundException { + TaskServiceImpl cutSpy = Mockito.spy(cut); + TaskImpl task = createUnitTestTask("12", "Task Name", "1"); + doReturn(task).when(cutSpy).getTaskById(task.getId()); + + try { + cutSpy.createTask(task); + } catch (TaskAlreadyExistException ex) { + verify(taskanaEngineImpl, times(1)).openConnection(); + verify(cutSpy, times(1)).getTaskById(task.getId()); + verify(taskanaEngineImpl, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl, + taskMapperMock, objectReferenceMapperMock, workbasketServiceMock, + classificationServiceMock); + throw ex; + } + } + @Test(expected = NotAuthorizedException.class) public void testCreateThrowingAuthorizedOnWorkbasket() - throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException { + throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, + TaskAlreadyExistException, TaskNotFoundException { + TaskServiceImpl cutSpy = Mockito.spy(cut); TaskImpl task = createUnitTestTask("1", "dummyTask", "1"); - doThrow(NotAuthorizedException.class).when(workbasketServiceMock).checkAuthorization(task.getWorkbasketId(), WorkbasketAuthorization.APPEND); + doThrow(TaskNotFoundException.class).when(cutSpy).getTaskById(task.getId()); + doThrow(NotAuthorizedException.class).when(workbasketServiceMock).checkAuthorization(task.getWorkbasketId(), + WorkbasketAuthorization.APPEND); try { - cut.createTask(task); + cutSpy.createTask(task); } catch (NotAuthorizedException e) { verify(taskanaEngineImpl, times(1)).openConnection(); + verify(cutSpy, times(1)).getTaskById(task.getId()); verify(workbasketServiceMock, times(1)).getWorkbasket(task.getWorkbasketId()); - verify(workbasketServiceMock, times(1)).checkAuthorization(task.getWorkbasketId(), WorkbasketAuthorization.APPEND); + verify(workbasketServiceMock, times(1)).checkAuthorization(task.getWorkbasketId(), + WorkbasketAuthorization.APPEND); verify(taskanaEngineImpl, times(1)).returnConnection(); verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl, taskMapperMock, objectReferenceMapperMock, workbasketServiceMock, @@ -298,13 +347,18 @@ public class TaskServiceImplTest { } @Test(expected = WorkbasketNotFoundException.class) - public void testCreateThrowsWorkbasketNotFoundException() throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException { + public void testCreateThrowsWorkbasketNotFoundException() + throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, + TaskAlreadyExistException, TaskNotFoundException { + TaskServiceImpl cutSpy = Mockito.spy(cut); TaskImpl task = createUnitTestTask("1", "dumma-task", "1"); + doThrow(TaskNotFoundException.class).when(cutSpy).getTaskById(task.getId()); doThrow(WorkbasketNotFoundException.class).when(workbasketServiceMock).getWorkbasket(any()); try { - cut.createTask(task); + cutSpy.createTask(task); } catch (WorkbasketNotFoundException e) { verify(taskanaEngineImpl, times(1)).openConnection(); + verify(cutSpy, times(1)).getTaskById(task.getId()); verify(workbasketServiceMock, times(1)).getWorkbasket(task.getWorkbasketId()); verify(taskanaEngineImpl, times(1)).returnConnection(); verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl, diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntAutocommitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntAutocommitTest.java index ce8d56b7a..f20efb4d2 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntAutocommitTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntAutocommitTest.java @@ -1,12 +1,15 @@ package pro.taskana.impl.integration; import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; import java.io.FileNotFoundException; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import javax.security.auth.login.LoginException; import javax.sql.DataSource; @@ -17,6 +20,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.runner.RunWith; import pro.taskana.Classification; import pro.taskana.ClassificationQuery; @@ -31,6 +35,7 @@ import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.exceptions.ClassificationAlreadyExistException; import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.TaskNotFoundException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.impl.ClassificationQueryImpl; @@ -41,14 +46,21 @@ import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.WorkbasketImpl; import pro.taskana.impl.configuration.DBCleaner; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; +import pro.taskana.impl.util.IdGenerator; +import pro.taskana.model.ClassificationImpl; import pro.taskana.model.TaskState; import pro.taskana.model.TaskSummary; +import pro.taskana.model.WorkbasketAccessItem; +import pro.taskana.security.CurrentUserContext; +import pro.taskana.security.JAASRunner; +import pro.taskana.security.WithAccessId; /** * Integration Test for TaskServiceImpl transactions with connection management mode AUTOCOMMIT. * * @author EH */ +@RunWith(JAASRunner.class) public class TaskServiceImplIntAutocommitTest { private DataSource dataSource; @@ -90,7 +102,7 @@ public class TaskServiceImplIntAutocommitTest { @Test public void testStart() throws FileNotFoundException, SQLException, TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedException, ClassificationNotFoundException, - ClassificationAlreadyExistException { + ClassificationAlreadyExistException, TaskAlreadyExistException { Workbasket wb = workbasketService.newWorkbasket(); wb.setName("workbasket"); taskanaEngine.getWorkbasketService().createWorkbasket(wb); @@ -115,7 +127,8 @@ public class TaskServiceImplIntAutocommitTest { @Test(expected = TaskNotFoundException.class) public void testStartTransactionFail() throws FileNotFoundException, SQLException, TaskNotFoundException, NotAuthorizedException, - WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException { + WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException, + TaskAlreadyExistException { Workbasket wb = workbasketService.newWorkbasket(); wb.setName("sdf"); taskanaEngine.getWorkbasketService().createWorkbasket(wb); @@ -138,7 +151,8 @@ public class TaskServiceImplIntAutocommitTest { @Test public void testCreateTaskInTaskanaWithDefaultDb() throws FileNotFoundException, SQLException, TaskNotFoundException, NotAuthorizedException, - WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException { + WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException, + TaskAlreadyExistException { Workbasket wb = workbasketService.newWorkbasket(); wb.setName("workbasket"); wb = taskanaEngine.getWorkbasketService().createWorkbasket(wb); @@ -158,7 +172,8 @@ public class TaskServiceImplIntAutocommitTest { @Test public void should_ReturnList_when_BuilderIsUsed() throws SQLException, NotAuthorizedException, - WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException { + WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException, + TaskAlreadyExistException { Workbasket wb = workbasketService.newWorkbasket(); wb.setName("workbasket"); taskanaEngine.getWorkbasketService().createWorkbasket(wb); @@ -206,7 +221,6 @@ public class TaskServiceImplIntAutocommitTest { @Test public void shouldReturnTaskSummaryListWithValues() throws Exception { - Workbasket dummyWorkbasket = workbasketService.newWorkbasket(); dummyWorkbasket.setName("Dummy-Basket"); dummyWorkbasket = workbasketService.createWorkbasket(dummyWorkbasket); @@ -254,6 +268,163 @@ public class TaskServiceImplIntAutocommitTest { taskServiceImpl.getTaskSummariesByWorkbasketId(wb.getId()); } + @Test + public void shouldTransferTaskToOtherWorkbasket() + throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException, + ClassificationAlreadyExistException, TaskNotFoundException, InterruptedException, TaskAlreadyExistException { + Workbasket sourceWB; + Workbasket destinationWB; + WorkbasketImpl wb; + ClassificationImpl classification; + TaskImpl task; + Task resultTask; + final int sleepTime = 100; + + // Source Workbasket + wb = (WorkbasketImpl) workbasketService.newWorkbasket(); + wb.setName("Basic-Workbasket"); + wb.setDescription("Just used as base WB for Task here"); + wb.setOwner("The Tester ID"); + sourceWB = workbasketService.createWorkbasket(wb); + + // Destination Workbasket + wb = (WorkbasketImpl) workbasketService.newWorkbasket(); + wb.setName("Desination-WorkBasket"); + wb.setDescription("Destination WB where Task should be transfered to"); + wb.setOwner("The Tester ID"); + destinationWB = workbasketService.createWorkbasket(wb); + + // Classification required for Task + classification = (ClassificationImpl) classificationService.newClassification(); + classification.setCategory("Test Classification"); + classification.setDomain("test-domain"); + classification.setName("Transfert-Task Classification"); + classification.setKey("KEY"); + classificationService.createClassification(classification); + + // Task which should be transfered + task = (TaskImpl) taskServiceImpl.newTask(); + task.setName("Task Name"); + task.setDescription("Task used for transfer Test"); + task.setWorkbasketId(sourceWB.getId()); + task.setRead(true); + task.setTransferred(false); + task.setModified(null); + task.setClassification(classification); + task = (TaskImpl) taskServiceImpl.createTask(task); + Thread.sleep(sleepTime); // Sleep for modification-timestamp + + resultTask = taskServiceImpl.transfer(task.getId(), destinationWB.getId()); + assertThat(resultTask.isRead(), equalTo(false)); + assertThat(resultTask.isTransferred(), equalTo(true)); + assertThat(resultTask.getWorkbasketId(), equalTo(destinationWB.getId())); + assertThat(resultTask.getModified(), not(equalTo(null))); + assertThat(resultTask.getModified(), not(equalTo(task.getModified()))); + assertThat(resultTask.getCreated(), not(equalTo(null))); + assertThat(resultTask.getCreated(), equalTo(task.getCreated())); + } + + @Test(expected = TaskNotFoundException.class) + public void shouldNotTransferAnyTask() + throws WorkbasketNotFoundException, NotAuthorizedException, TaskNotFoundException { + taskServiceImpl.transfer(UUID.randomUUID() + "_X", "1"); + } + + @WithAccessId(userName = "User") + @Test + public void shouldNotTransferByFailingSecurity() throws WorkbasketNotFoundException, + ClassificationNotFoundException, NotAuthorizedException, ClassificationAlreadyExistException, SQLException, + TaskNotFoundException, TaskAlreadyExistException { + final String user = CurrentUserContext.getUserid(); + + // Set up Security for this Test + dataSource = TaskanaEngineConfigurationTest.getDataSource(); + taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false, true); + taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); + taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; + taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); + taskServiceImpl = (TaskServiceImpl) taskanaEngine.getTaskService(); + classificationService = taskanaEngine.getClassificationService(); + workbasketService = taskanaEngine.getWorkbasketService(); + + ClassificationImpl classification = (ClassificationImpl) classificationService.newClassification(); + classification.setCategory("Test Classification"); + classification.setDomain("test-domain"); + classification.setName("Transfert-Task Classification"); + classification.setKey("KEY"); + classificationService.createClassification(classification); + + WorkbasketImpl wb = (WorkbasketImpl) workbasketService.newWorkbasket(); + wb.setName("BASE WB"); + wb.setDescription("Normal base WB"); + wb.setOwner(user); + wb = (WorkbasketImpl) workbasketService.createWorkbasket(wb); + createWorkbasketWithSecurity(wb, wb.getOwner(), true, true, true, true); + + WorkbasketImpl wbNoAppend = (WorkbasketImpl) workbasketService.newWorkbasket(); + wbNoAppend.setName("Test-Security-WorkBasket-APPEND"); + wbNoAppend.setDescription("Workbasket without permission APPEND on Task"); + wbNoAppend.setOwner(user); + wbNoAppend = (WorkbasketImpl) workbasketService.createWorkbasket(wbNoAppend); + createWorkbasketWithSecurity(wbNoAppend, wbNoAppend.getOwner(), true, true, false, true); + + WorkbasketImpl wbNoTransfer = (WorkbasketImpl) workbasketService.newWorkbasket(); + wbNoTransfer.setName("Test-Security-WorkBasket-TRANSFER"); + wbNoTransfer.setDescription("Workbasket without permission TRANSFER on Task"); + wbNoTransfer.setOwner(user); + wbNoTransfer = (WorkbasketImpl) workbasketService.createWorkbasket(wbNoTransfer); + createWorkbasketWithSecurity(wbNoTransfer, wbNoTransfer.getOwner(), true, true, true, false); + + TaskImpl task = (TaskImpl) taskServiceImpl.newTask(); + task.setName("Task Name"); + task.setDescription("Task used for transfer Test"); + task.setWorkbasketId(wb.getId()); + task.setOwner(user); + task.setClassification(classification); + task = (TaskImpl) taskServiceImpl.createTask(task); + + // Check failing with missing APPEND + try { + task = (TaskImpl) taskServiceImpl.transfer(task.getId(), wbNoAppend.getId()); + fail("Transfer Task should be FAILD, because there are no APPEND-Rights on destination WB."); + } catch (NotAuthorizedException e) { + if (!e.getMessage().contains("APPEND")) { + fail("Transfer Task should be FAILD, because there are no APPEND-Rights on destination WB."); + } + assertThat(task.isTransferred(), equalTo(false)); + assertThat(task.getWorkbasketId(), not(equalTo(wbNoAppend.getId()))); + assertThat(task.getWorkbasketId(), equalTo(wb.getId())); + } + + // Check failing with missing TRANSFER + task.setId(UUID.randomUUID().toString()); + task.setWorkbasketId(wbNoTransfer.getId()); + task = (TaskImpl) taskServiceImpl.createTask(task); + try { + task = (TaskImpl) taskServiceImpl.transfer(task.getId(), wb.getId()); + fail("Transfer Task should be FAILD, because there are no TRANSFER-Rights on current WB."); + } catch (NotAuthorizedException e) { + if (!e.getMessage().contains("TRANSFER")) { + fail("Transfer Task should be FAILD, because there are no APPEND-Rights on current WB."); + } + assertThat(task.isTransferred(), equalTo(false)); + assertThat(task.getWorkbasketId(), not(equalTo(wbNoAppend.getId()))); + } + } + + private void createWorkbasketWithSecurity(Workbasket wb, String accessId, boolean permOpen, + boolean permRead, boolean permAppend, boolean permTransfer) { + WorkbasketAccessItem accessItem = new WorkbasketAccessItem(); + accessItem.setId(IdGenerator.generateWithPrefix("WAI")); + accessItem.setWorkbasketId(wb.getId()); + accessItem.setAccessId(accessId); + accessItem.setPermOpen(permOpen); + accessItem.setPermRead(permRead); + accessItem.setPermAppend(permAppend); + accessItem.setPermTransfer(permTransfer); + workbasketService.createWorkbasketAuthorization(accessItem); + } + @AfterClass public static void cleanUpClass() { FileUtils.deleteRecursive("~/data", true); diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntExplicitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntExplicitTest.java index cddb3b1a9..833d483ff 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntExplicitTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntExplicitTest.java @@ -1,11 +1,17 @@ package pro.taskana.impl.integration; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + import java.io.FileNotFoundException; import java.sql.Connection; import java.sql.SQLException; import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.List; +import java.util.UUID; import javax.security.auth.login.LoginException; import javax.sql.DataSource; @@ -32,11 +38,13 @@ import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.exceptions.ClassificationAlreadyExistException; import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.TaskNotFoundException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.impl.ClassificationQueryImpl; import pro.taskana.impl.ClassificationServiceImpl; import pro.taskana.impl.ObjectReferenceQueryImpl; +import pro.taskana.impl.TaskImpl; import pro.taskana.impl.TaskServiceImpl; import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.WorkbasketImpl; @@ -48,23 +56,31 @@ import pro.taskana.model.ClassificationImpl; import pro.taskana.model.ObjectReference; import pro.taskana.model.TaskState; import pro.taskana.model.WorkbasketAccessItem; +import pro.taskana.security.CurrentUserContext; import pro.taskana.security.JAASRunner; import pro.taskana.security.WithAccessId; /** * Integration Test for TaskServiceImpl transactions with connection management mode EXPLICIT. + * * @author EH */ @RunWith(JAASRunner.class) public class TaskServiceImplIntExplicitTest { private DataSource dataSource; + private TaskServiceImpl taskServiceImpl; + private TaskanaEngineConfiguration taskanaEngineConfiguration; + private TaskanaEngine taskanaEngine; + private TaskanaEngineImpl taskanaEngineImpl; + private ClassificationService classificationService; - private WorkbasketService workBasketService; + + private WorkbasketService workbasketService; @BeforeClass public static void resetDb() throws SQLException { @@ -82,7 +98,7 @@ public class TaskServiceImplIntExplicitTest { taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; classificationService = taskanaEngine.getClassificationService(); taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT); - workBasketService = taskanaEngine.getWorkbasketService(); + workbasketService = taskanaEngine.getWorkbasketService(); DBCleaner cleaner = new DBCleaner(); cleaner.clearDb(dataSource, false); } @@ -90,13 +106,15 @@ public class TaskServiceImplIntExplicitTest { @WithAccessId(userName = "Elena") @Test(expected = TaskNotFoundException.class) public void testStartTransactionFail() - throws FileNotFoundException, SQLException, TaskNotFoundException, NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException { + throws FileNotFoundException, SQLException, TaskNotFoundException, NotAuthorizedException, + WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException, + TaskAlreadyExistException { Connection connection = dataSource.getConnection(); taskanaEngineImpl.setConnection(connection); generateSampleAccessItems(); - WorkbasketImpl workbasket = (WorkbasketImpl) workBasketService.newWorkbasket(); + WorkbasketImpl workbasket = (WorkbasketImpl) workbasketService.newWorkbasket(); workbasket.setName("workbasket"); workbasket.setId("1"); // set id manually for authorization tests Classification classification = classificationService.newClassification(); @@ -120,7 +138,10 @@ public class TaskServiceImplIntExplicitTest { @WithAccessId(userName = "Elena") @Test - public void testCreateTask() throws FileNotFoundException, SQLException, TaskNotFoundException, NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException { + public void testCreateTask() + throws FileNotFoundException, SQLException, TaskNotFoundException, NotAuthorizedException, + WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException, + TaskAlreadyExistException { Connection connection = dataSource.getConnection(); taskanaEngineImpl.setConnection(connection); @@ -140,22 +161,24 @@ public class TaskServiceImplIntExplicitTest { @Test public void testCreateTaskInTaskanaWithDefaultDb() - throws FileNotFoundException, SQLException, TaskNotFoundException, NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException { + throws FileNotFoundException, SQLException, TaskNotFoundException, NotAuthorizedException, + WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException, + TaskAlreadyExistException { DataSource ds = TaskanaEngineConfiguration.createDefaultDataSource(); TaskanaEngineConfiguration taskanaEngineConfiguration = new TaskanaEngineConfiguration(ds, false, false); TaskanaEngine te = taskanaEngineConfiguration.buildTaskanaEngine(); Connection connection = ds.getConnection(); te.setConnection(connection); TaskServiceImpl taskServiceImpl = (TaskServiceImpl) te.getTaskService(); - WorkbasketServiceImpl workbasketServiceImpl = (WorkbasketServiceImpl) te.getWorkbasketService(); + WorkbasketServiceImpl workBasketServiceImpl = (WorkbasketServiceImpl) te.getWorkbasketService(); ClassificationServiceImpl classificationServiceImpl = (ClassificationServiceImpl) te.getClassificationService(); - Workbasket workbasket = workBasketService.newWorkbasket(); + Workbasket workbasket = workbasketService.newWorkbasket(); workbasket.setName("workbasket"); Classification classification = classificationService.newClassification(); classification.setKey("TEST"); workbasket.setName("workbasket99"); - workbasketServiceImpl.createWorkbasket(workbasket); + workBasketServiceImpl.createWorkbasket(workbasket); classificationServiceImpl.createClassification(classification); Task task = taskServiceImpl.newTask(); @@ -172,7 +195,9 @@ public class TaskServiceImplIntExplicitTest { @WithAccessId(userName = "Elena") @Test - public void testCreateTaskWithPlannedAndName() throws SQLException, NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException { + public void testCreateTaskWithPlannedAndName() throws SQLException, NotAuthorizedException, + WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException, + TaskAlreadyExistException { Connection connection = dataSource.getConnection(); taskanaEngineImpl.setConnection(connection); @@ -221,7 +246,9 @@ public class TaskServiceImplIntExplicitTest { @WithAccessId(userName = "Elena") @Test(expected = WorkbasketNotFoundException.class) - public void createTaskShouldThrowWorkbasketNotFoundException() throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, SQLException, ClassificationAlreadyExistException { + public void createTaskShouldThrowWorkbasketNotFoundException() + throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, SQLException, + ClassificationAlreadyExistException, TaskAlreadyExistException { Connection connection = dataSource.getConnection(); taskanaEngineImpl.setConnection(connection); @@ -234,7 +261,9 @@ public class TaskServiceImplIntExplicitTest { @WithAccessId(userName = "Elena") @Test(expected = ClassificationNotFoundException.class) - public void createManualTaskShouldThrowClassificationNotFoundException() throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, SQLException, ClassificationAlreadyExistException { + public void createManualTaskShouldThrowClassificationNotFoundException() + throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, SQLException, + ClassificationAlreadyExistException, TaskAlreadyExistException { Connection connection = dataSource.getConnection(); taskanaEngineImpl.setConnection(connection); @@ -245,15 +274,17 @@ public class TaskServiceImplIntExplicitTest { taskServiceImpl.createTask(test); } - @WithAccessId(userName = "Elena", groupNames = {"DummyGroup"}) + @WithAccessId(userName = "Elena", groupNames = { "DummyGroup" }) @Test - public void should_ReturnList_when_BuilderIsUsed() throws SQLException, NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException { + public void should_ReturnList_when_BuilderIsUsed() throws SQLException, NotAuthorizedException, + WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException, + TaskAlreadyExistException { Connection connection = dataSource.getConnection(); taskanaEngineImpl.setConnection(connection); generateSampleAccessItems(); - WorkbasketImpl workbasket = (WorkbasketImpl) workBasketService.newWorkbasket(); + WorkbasketImpl workbasket = (WorkbasketImpl) workbasketService.newWorkbasket(); workbasket.setName("workbasket"); Classification classification = classificationService.newClassification(); classification.setKey("TEST"); @@ -269,24 +300,196 @@ public class TaskServiceImplIntExplicitTest { TaskanaEngineImpl taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; ClassificationQuery classificationQuery = new ClassificationQueryImpl(taskanaEngineImpl) - .parentClassificationKey("pId1", "pId2").category("cat1", "cat2").type("oneType").name("1Name", "name2") - .descriptionLike("my desc").priority(1, 2, 1).serviceLevel("me", "and", "you"); + .parentClassificationKey("pId1", "pId2") + .category("cat1", "cat2") + .type("oneType") + .name("1Name", "name2") + .descriptionLike("my desc") + .priority(1, 2, 1) + .serviceLevel("me", "and", "you"); ObjectReferenceQuery objectReferenceQuery = new ObjectReferenceQueryImpl(taskanaEngineImpl) - .company("first comp", "sonstwo gmbh").system("sys").type("type1", "type2") - .systemInstance("sysInst1", "sysInst2").value("val1", "val2", "val3"); + .company("first comp", "sonstwo gmbh") + .system("sys") + .type("type1", "type2") + .systemInstance("sysInst1", "sysInst2") + .value("val1", "val2", "val3"); - List results = taskServiceImpl.createTaskQuery().name("bla", "test").descriptionLike("test") - .priority(1, 2, 2).state(TaskState.CLAIMED).workbasketId("1", "2") - .owner("test", "test2", "bla").customFields("test").classification(classificationQuery) - .objectReference(objectReferenceQuery).list(); + List results = taskServiceImpl.createTaskQuery() + .name("bla", "test") + .descriptionLike("test") + .priority(1, 2, 2) + .state(TaskState.CLAIMED) + .workbasketId("1", "2") + .owner("test", "test2", "bla") + .customFields("test") + .classification(classificationQuery) + .objectReference(objectReferenceQuery) + .list(); Assert.assertEquals(0, results.size()); connection.commit(); } + @WithAccessId(userName = "Elena") + @Test + public void shouldTransferTaskToOtherWorkbasket() + throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException, + ClassificationAlreadyExistException, TaskNotFoundException, InterruptedException, TaskAlreadyExistException, + SQLException { + Workbasket sourceWB; + Workbasket destinationWB; + WorkbasketImpl wb; + ClassificationImpl classification; + TaskImpl task; + Task resultTask; + final int sleepTime = 100; + final String user = CurrentUserContext.getUserid(); + Connection connection = dataSource.getConnection(); + taskanaEngineImpl.setConnection(connection); + + // Source Workbasket + wb = (WorkbasketImpl) workbasketService.newWorkbasket(); + wb.setName("Basic-Workbasket"); + wb.setDescription("Just used as base WB for Task here"); + wb.setOwner(user); + sourceWB = workbasketService.createWorkbasket(wb); + createWorkbasketWithSecurity(wb, wb.getOwner(), false, false, false, false); + createWorkbasketWithSecurity(sourceWB, sourceWB.getOwner(), false, false, true, true); + + // Destination Workbasket + wb = (WorkbasketImpl) workbasketService.newWorkbasket(); + wb.setName("Desination-WorkBasket"); + wb.setDescription("Destination WB where Task should be transfered to"); + wb.setOwner(user); + destinationWB = workbasketService.createWorkbasket(wb); + createWorkbasketWithSecurity(destinationWB, destinationWB.getOwner(), false, false, true, true); + + // Classification required for Task + classification = (ClassificationImpl) classificationService.newClassification(); + classification.setCategory("Test Classification"); + classification.setDomain("test-domain"); + classification.setName("Transfert-Task Classification"); + classification.setKey("KEY"); + classificationService.createClassification(classification); + + // Task which should be transfered + task = (TaskImpl) taskServiceImpl.newTask(); + task.setName("Task Name"); + task.setDescription("Task used for transfer Test"); + task.setWorkbasketId(sourceWB.getId()); + task.setRead(true); + task.setTransferred(false); + task.setModified(null); + task.setClassification(classification); + task.setOwner(user); + task = (TaskImpl) taskServiceImpl.createTask(task); + Thread.sleep(sleepTime); // Sleep for modification-timestamp + connection.commit(); + + resultTask = taskServiceImpl.transfer(task.getId(), destinationWB.getId()); + connection.commit(); + assertThat(resultTask.isRead(), equalTo(false)); + assertThat(resultTask.isTransferred(), equalTo(true)); + assertThat(resultTask.getWorkbasketId(), equalTo(destinationWB.getId())); + assertThat(resultTask.getModified(), not(equalTo(null))); + assertThat(resultTask.getModified(), not(equalTo(task.getModified()))); + assertThat(resultTask.getCreated(), not(equalTo(null))); + assertThat(resultTask.getCreated(), equalTo(task.getCreated())); + } + + @Test(expected = TaskNotFoundException.class) + public void shouldNotTransferAnyTask() + throws WorkbasketNotFoundException, NotAuthorizedException, TaskNotFoundException, SQLException { + Connection connection = dataSource.getConnection(); + taskanaEngineImpl.setConnection(connection); + taskServiceImpl.transfer(UUID.randomUUID() + "_X", "1"); + } + + @WithAccessId(userName = "User") + @Test + public void shouldNotTransferByFailingSecurity() throws WorkbasketNotFoundException, + ClassificationNotFoundException, NotAuthorizedException, ClassificationAlreadyExistException, SQLException, + TaskNotFoundException, TaskAlreadyExistException { + final String user = "User"; + + // Set up Security for this Test + dataSource = TaskanaEngineConfigurationTest.getDataSource(); + taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false, true); + taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); + taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; + taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); + taskServiceImpl = (TaskServiceImpl) taskanaEngine.getTaskService(); + classificationService = taskanaEngine.getClassificationService(); + workbasketService = taskanaEngine.getWorkbasketService(); + + ClassificationImpl classification = (ClassificationImpl) classificationService.newClassification(); + classification.setCategory("Test Classification"); + classification.setDomain("test-domain"); + classification.setName("Transfert-Task Classification"); + classification.setKey("KEY"); + classificationService.createClassification(classification); + + WorkbasketImpl wb = (WorkbasketImpl) workbasketService.newWorkbasket(); + wb.setName("BASE WB"); + wb.setDescription("Normal base WB"); + wb.setOwner(user); + wb = (WorkbasketImpl) workbasketService.createWorkbasket(wb); + createWorkbasketWithSecurity(wb, wb.getOwner(), true, true, true, true); + + WorkbasketImpl wbNoAppend = (WorkbasketImpl) workbasketService.newWorkbasket(); + wbNoAppend.setName("Test-Security-WorkBasket-APPEND"); + wbNoAppend.setDescription("Workbasket without permission APPEND on Task"); + wbNoAppend.setOwner(user); + wbNoAppend = (WorkbasketImpl) workbasketService.createWorkbasket(wbNoAppend); + createWorkbasketWithSecurity(wbNoAppend, wbNoAppend.getOwner(), true, true, false, true); + + WorkbasketImpl wbNoTransfer = (WorkbasketImpl) workbasketService.newWorkbasket(); + wbNoTransfer.setName("Test-Security-WorkBasket-TRANSFER"); + wbNoTransfer.setDescription("Workbasket without permission TRANSFER on Task"); + wbNoTransfer.setOwner(user); + wbNoTransfer = (WorkbasketImpl) workbasketService.createWorkbasket(wbNoTransfer); + createWorkbasketWithSecurity(wbNoTransfer, wbNoTransfer.getOwner(), true, true, true, false); + + TaskImpl task = (TaskImpl) taskServiceImpl.newTask(); + task.setName("Task Name"); + task.setDescription("Task used for transfer Test"); + task.setWorkbasketId(wb.getId()); + task.setOwner(user); + task.setClassification(classification); + task = (TaskImpl) taskServiceImpl.createTask(task); + + // Check failing with missing APPEND + try { + task = (TaskImpl) taskServiceImpl.transfer(task.getId(), wbNoAppend.getId()); + fail("Transfer Task should be FAILD, because there are no APPEND-Rights on destination WB."); + } catch (NotAuthorizedException e) { + if (!e.getMessage().contains("APPEND")) { + fail("Transfer Task should be FAILD, because there are no APPEND-Rights on destination WB."); + } + assertThat(task.isTransferred(), equalTo(false)); + assertThat(task.getWorkbasketId(), not(equalTo(wbNoAppend.getId()))); + assertThat(task.getWorkbasketId(), equalTo(wb.getId())); + } + + // Check failing with missing TRANSFER + task.setId(UUID.randomUUID().toString()); + task.setWorkbasketId(wbNoTransfer.getId()); + task = (TaskImpl) taskServiceImpl.createTask(task); + try { + task = (TaskImpl) taskServiceImpl.transfer(task.getId(), wb.getId()); + fail("Transfer Task should be FAILD, because there are no TRANSFER-Rights on current WB."); + } catch (NotAuthorizedException e) { + if (!e.getMessage().contains("TRANSFER")) { + fail("Transfer Task should be FAILD, because there are no APPEND-Rights on current WB."); + } + assertThat(task.isTransferred(), equalTo(false)); + assertThat(task.getWorkbasketId(), not(equalTo(wbNoAppend.getId()))); + } + } + private Task generateDummyTask() throws ClassificationAlreadyExistException { - WorkbasketImpl workbasket = (WorkbasketImpl) workBasketService.newWorkbasket(); + WorkbasketImpl workbasket = (WorkbasketImpl) workbasketService.newWorkbasket(); workbasket.setName("wb"); workbasket.setId("1"); // set id manually for authorization tests taskanaEngine.getWorkbasketService().createWorkbasket(workbasket); @@ -308,14 +511,27 @@ public class TaskServiceImplIntExplicitTest { accessItem.setAccessId("Elena"); accessItem.setPermAppend(true); accessItem.setPermOpen(true); - workBasketService.createWorkbasketAuthorization(accessItem); + workbasketService.createWorkbasketAuthorization(accessItem); WorkbasketAccessItem accessItem2 = new WorkbasketAccessItem(); accessItem2.setId(IdGenerator.generateWithPrefix("WAI")); accessItem2.setWorkbasketId("2"); accessItem2.setAccessId("DummyGroup"); accessItem2.setPermOpen(true); - workBasketService.createWorkbasketAuthorization(accessItem2); + workbasketService.createWorkbasketAuthorization(accessItem2); + } + + private void createWorkbasketWithSecurity(Workbasket wb, String accessId, boolean permOpen, + boolean permRead, boolean permAppend, boolean permTransfer) { + WorkbasketAccessItem accessItem = new WorkbasketAccessItem(); + accessItem.setId(IdGenerator.generateWithPrefix("WAI")); + accessItem.setWorkbasketId(wb.getId()); + accessItem.setAccessId(accessId); + accessItem.setPermOpen(permOpen); + accessItem.setPermRead(permRead); + accessItem.setPermAppend(permAppend); + accessItem.setPermTransfer(permTransfer); + workbasketService.createWorkbasketAuthorization(accessItem); } @After diff --git a/lib/taskana-spring-example/src/main/java/pro/taskana/ExampleBootstrap.java b/lib/taskana-spring-example/src/main/java/pro/taskana/ExampleBootstrap.java index 1811aee44..b8f1eccdb 100644 --- a/lib/taskana-spring-example/src/main/java/pro/taskana/ExampleBootstrap.java +++ b/lib/taskana-spring-example/src/main/java/pro/taskana/ExampleBootstrap.java @@ -10,6 +10,7 @@ import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.exceptions.InvalidOwnerException; import pro.taskana.exceptions.InvalidStateException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.TaskNotFoundException; import pro.taskana.exceptions.WorkbasketNotFoundException; @@ -17,22 +18,23 @@ import pro.taskana.exceptions.WorkbasketNotFoundException; @Transactional public class ExampleBootstrap { - @Autowired - private TaskService taskService; + @Autowired + private TaskService taskService; - @PostConstruct - public void test() throws TaskNotFoundException, NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, InvalidStateException, InvalidOwnerException { - System.out.println("---------------------------> Start App"); - Task task = taskService.newTask(); - task.setName("Spring example task"); - task.setWorkbasketId("1"); - task = taskService.createTask(task); - System.out.println("---------------------------> Task started: " + task.getId()); - taskService.claim(task.getId()); - System.out.println( - "---------------------------> Task claimed: " + taskService.getTaskById(task.getId()).getOwner()); - taskService.completeTask(task.getId(), true); - System.out.println("---------------------------> Task completed"); - } + @PostConstruct + public void test() throws TaskNotFoundException, NotAuthorizedException, WorkbasketNotFoundException, + ClassificationNotFoundException, InvalidStateException, InvalidOwnerException, TaskAlreadyExistException { + System.out.println("---------------------------> Start App"); + Task task = taskService.newTask(); + task.setName("Spring example task"); + task.setWorkbasketId("1"); + task = taskService.createTask(task); + System.out.println("---------------------------> Task started: " + task.getId()); + taskService.claim(task.getId()); + System.out.println( + "---------------------------> Task claimed: " + taskService.getTaskById(task.getId()).getOwner()); + taskService.completeTask(task.getId(), true); + System.out.println("---------------------------> Task completed"); + } } diff --git a/lib/taskana-spring/src/test/java/pro/taskana/TaskanaComponent.java b/lib/taskana-spring/src/test/java/pro/taskana/TaskanaComponent.java index 358628a28..1c87c7bb9 100644 --- a/lib/taskana-spring/src/test/java/pro/taskana/TaskanaComponent.java +++ b/lib/taskana-spring/src/test/java/pro/taskana/TaskanaComponent.java @@ -6,24 +6,26 @@ import org.springframework.transaction.annotation.Transactional; import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.WorkbasketNotFoundException; @Component @Transactional public class TaskanaComponent { - @Autowired - TaskService taskService; + @Autowired + TaskService taskService; - public TaskService getTaskService() { - return taskService; - } + public TaskService getTaskService() { + return taskService; + } - public void triggerRollback() throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException { - Task task = taskService.newTask(); - task.setName("Unit Test Task"); - task.setWorkbasketId("1"); - task = taskService.createTask(task); - throw new RuntimeException(); - } + public void triggerRollback() throws NotAuthorizedException, WorkbasketNotFoundException, + ClassificationNotFoundException, TaskAlreadyExistException { + Task task = taskService.newTask(); + task.setName("Unit Test Task"); + task.setWorkbasketId("1"); + task = taskService.createTask(task); + throw new RuntimeException(); + } }