Skip to content
This repository has been archived by the owner on Feb 13, 2021. It is now read-only.

Commit

Permalink
1812 Add REST APIs to delete a task
Browse files Browse the repository at this point in the history
- fix getTaskById() to throw ResourceNotFoundException when not found
- add "DELETE /v1/tasks/{taskId}" endpont
- add tests for endpoint and service method
- handle engine ENTITY_DDELETED event
- add tests for event hendler
- use TaskStatus enum instead String in Task model
- add tests for TaskConverter

Activiti/Activiti#1812
  • Loading branch information
Constantin Ciobotaru authored and Constantin Ciobotaru committed Apr 17, 2018
1 parent d7da6dc commit e98d533
Show file tree
Hide file tree
Showing 20 changed files with 724 additions and 35 deletions.
Expand Up @@ -25,7 +25,7 @@
public class Task {

public enum TaskStatus {
CREATED, ASSIGNED, SUSPENDED
CREATED, ASSIGNED, SUSPENDED, CANCELLED
}

private String id;
Expand All @@ -40,7 +40,7 @@ public enum TaskStatus {
private String processDefinitionId;
private String processInstanceId;
private String parentTaskId;
private String status;
private TaskStatus status;

public Task() {
}
Expand All @@ -57,7 +57,7 @@ public Task(String id,
String processDefinitionId,
String processInstanceId,
String parentTaskId,
String status) {
TaskStatus status) {
this.id = id;
this.owner = owner;
this.assignee = assignee;
Expand Down Expand Up @@ -125,7 +125,7 @@ public String getProcessInstanceId() {
return processInstanceId;
}

public String getStatus() {
public TaskStatus getStatus() {
return status;
}

Expand Down
Expand Up @@ -17,9 +17,16 @@

import java.util.List;

import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.activiti.cloud.services.api.model.Task.TaskStatus;

import static org.activiti.cloud.services.api.model.Task.TaskStatus.CREATED;
import static org.activiti.cloud.services.api.model.Task.TaskStatus.SUSPENDED;
import static org.activiti.cloud.services.api.model.Task.TaskStatus.ASSIGNED;
import static org.activiti.cloud.services.api.model.Task.TaskStatus.CANCELLED;

@Component
public class TaskConverter implements ModelConverter<Task, org.activiti.cloud.services.api.model.Task> {
Expand Down Expand Up @@ -52,13 +59,16 @@ public org.activiti.cloud.services.api.model.Task from(Task source) {
return task;
}

private String calculateStatus(Task source) {
if (source.isSuspended()) {
return org.activiti.cloud.services.api.model.Task.TaskStatus.SUSPENDED.name();
private TaskStatus calculateStatus(Task source) {
if (source instanceof TaskEntity &&
(((TaskEntity) source).isDeleted() || ((TaskEntity) source).isCanceled())) {
return CANCELLED;
} else if (source.isSuspended()) {
return SUSPENDED;
} else if (source.getAssignee() != null && !source.getAssignee().isEmpty()) {
return org.activiti.cloud.services.api.model.Task.TaskStatus.ASSIGNED.name();
return ASSIGNED;
}
return org.activiti.cloud.services.api.model.Task.TaskStatus.CREATED.name();
return CREATED;
}

@Override
Expand Down
@@ -0,0 +1,128 @@
/*
* Copyright 2018 Alfresco, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.activiti.cloud.services.api.converter;

import java.util.Date;

import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.task.Task;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
* Mock task builder
*/
public class MockTaskBuilder {

private Task task;

private MockTaskBuilder(Class<? extends Task> taskClass) {
task = mock(taskClass);
}

public static MockTaskBuilder taskBuilder() {
return new MockTaskBuilder(Task.class);
}

public static MockTaskBuilder taskEntityBuilder() {
return new MockTaskBuilder(TaskEntity.class);
}

public MockTaskBuilder withId(String id) {
when(task.getId()).thenReturn(id);
return this;
}

public MockTaskBuilder withOwner(String owner) {
when(task.getOwner()).thenReturn(owner);
return this;
}

public MockTaskBuilder withAssignee(String assignee) {
when(task.getAssignee()).thenReturn(assignee);
return this;
}

public MockTaskBuilder withName(String name) {
when(task.getName()).thenReturn(name);
return this;
}

public MockTaskBuilder withDescription(String description) {
when(task.getDescription()).thenReturn(description);
return this;
}

public MockTaskBuilder withCreatedDate(Date createdDate) {
when(task.getCreateTime()).thenReturn(createdDate);
return this;
}

public MockTaskBuilder withClaimedDate(Date claimedDate) {
when(task.getClaimTime()).thenReturn(claimedDate);
return this;
}

public MockTaskBuilder withDueDate(Date dueDate) {
when(task.getDueDate()).thenReturn(dueDate);
return this;
}

public MockTaskBuilder withPriority(int priority) {
when(task.getPriority()).thenReturn(priority);
return this;
}

public MockTaskBuilder withProcessDefinitionId(String processDefinitionId) {
when(task.getProcessDefinitionId()).thenReturn(processDefinitionId);
return this;
}

public MockTaskBuilder withProcessInstanceId(String processInstanceId) {
when(task.getProcessInstanceId()).thenReturn(processInstanceId);
return this;
}

public MockTaskBuilder withParentTaskId(String parentTaskId) {
when(task.getParentTaskId()).thenReturn(parentTaskId);
return this;
}

public MockTaskBuilder withSuspended(boolean suspended) {
when(task.isSuspended()).thenReturn(suspended);
return this;
}

public MockTaskBuilder withCancalled(boolean cancelled) {
if (task instanceof TaskEntity) {
when(((TaskEntity) task).isCanceled()).thenReturn(cancelled);
}
return this;
}

public MockTaskBuilder withDeleted(boolean deleted) {
if (task instanceof TaskEntity) {
when(((TaskEntity) task).isDeleted()).thenReturn(deleted);
}
return this;
}

public Task build() {
return task;
}
}
@@ -0,0 +1,163 @@
/*
* Copyright 2018 Alfresco, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.activiti.cloud.services.api.converter;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.activiti.cloud.services.api.model.Task;
import org.activiti.cloud.services.api.model.converter.ListConverter;
import org.activiti.cloud.services.api.model.converter.TaskConverter;
import org.junit.Before;
import org.junit.Test;

import static org.activiti.cloud.services.api.converter.MockTaskBuilder.taskBuilder;
import static org.activiti.cloud.services.api.converter.MockTaskBuilder.taskEntityBuilder;
import static org.activiti.cloud.services.api.model.Task.TaskStatus.ASSIGNED;
import static org.activiti.cloud.services.api.model.Task.TaskStatus.CANCELLED;
import static org.activiti.cloud.services.api.model.Task.TaskStatus.CREATED;
import static org.activiti.cloud.services.api.model.Task.TaskStatus.SUSPENDED;
import static org.assertj.core.api.Assertions.*;

/**
* Tests for {@link TaskConverter}
*/
public class TaskConverterTest {

private TaskConverter taskConverter;

@Before
public void setUp() {
taskConverter = new TaskConverter(new ListConverter());
}

/**
* Test that all task fields are present in the converted task
*/
@Test
public void testConvertFromTask() {
//WHEN
Date now = new Date();
Task convertedTask = taskConverter.from(
taskBuilder()
.withId("testTaskId")
.withAssignee("testUser")
.withName("testTaskName")
.withDescription("testTaskDescription")
.withCreatedDate(now)
.withClaimedDate(now)
.withDueDate(now)
.withPriority(112)
.withProcessDefinitionId("testProcessDefinitionId")
.withProcessInstanceId("testProcessInstanceId")
.withParentTaskId("testParentTaskId")
.build()
);

//THEN
assertThat(convertedTask)
.isNotNull()
.extracting(Task::getId,
Task::getAssignee,
Task::getName,
Task::getDescription,
Task::getCreatedDate,
Task::getClaimedDate,
Task::getDueDate,
Task::getPriority,
Task::getProcessDefinitionId,
Task::getProcessInstanceId,
Task::getParentTaskId,
Task::getStatus)
.containsExactly("testTaskId",
"testUser",
"testTaskName",
"testTaskDescription",
now,
now,
now,
112,
"testProcessDefinitionId",
"testProcessInstanceId",
"testParentTaskId",
ASSIGNED);
}

/**
* Test that all tasks from a list are converted when dedicated from() method id used
*/
@Test
public void testConvertFromTasksList() {
//WHEN
List<Task> convertedTasks = taskConverter.from(Arrays.asList(
taskEntityBuilder().withId("testTaskId1").build(),
taskEntityBuilder().withId("testTaskId2").build()
));

//THEN
assertThat(convertedTasks)
.isNotEmpty()
.extracting(Task::getId)
.containsExactly("testTaskId1",
"testTaskId2");
}

/**
* Test that computed status for a cancelled task is CANCELLED
*/
@Test
public void testCalculateStatusCancelledTask() {
assertThat(taskConverter.from(taskEntityBuilder().withCancalled(true).build()))
.isNotNull()
.extracting(Task::getStatus)
.containsExactly(CANCELLED);
}

/**
* Test that computed status for a suspended task is SUSPENDED
*/
@Test
public void testCalculateStatusSuspendedTask() {
assertThat(taskConverter.from(taskEntityBuilder().withSuspended(true).build()))
.isNotNull()
.extracting(Task::getStatus)
.containsExactly(SUSPENDED);
}

/**
* Test that computed status for a assigned task is ASSIGNED
*/
@Test
public void testCalculateStatusAssignedTask() {
assertThat(taskConverter.from(taskBuilder().withAssignee("testUser").build()))
.isNotNull()
.extracting(Task::getStatus)
.containsExactly(ASSIGNED);
}

/**
* Test that computed status for a not assigned task is CREATED
*/
@Test
public void testCalculateStatusCreatedTask() {
assertThat(taskConverter.from(taskBuilder().build()))
.isNotNull()
.extracting(Task::getStatus)
.containsExactly(CREATED);
}
}
Expand Up @@ -200,6 +200,26 @@ public void setTaskVariablesLocal(SetTaskVariablesCmd setTaskVariablesCmd) {
setTaskVariablesCmd.getVariables());
}

/**
* Delete task by id.
* @param taskId the task id to delete
*/
public void deleteTask(String taskId) {
Task task = getTaskById(taskId);
if (task == null) {
throw new ActivitiObjectNotFoundException("Unable to find task for the given id: " + taskId);
}

checkWritePermissionsOnTask(task);

taskService.deleteTask(taskId,
"Cancelled by " + authenticationWrapper.getAuthenticatedUserId());
}

public void checkWritePermissionsOnTask(Task task) {
//TODO: to check the user write permissions on task
}

public Task createNewTask(CreateTaskCmd createTaskCmd) {
final org.activiti.engine.task.Task task = taskService.newTask();
task.setName(createTaskCmd.getName());
Expand Down

0 comments on commit e98d533

Please sign in to comment.