TSK-1150: Added REST-API for task comments
This commit is contained in:
parent
bebb60dea0
commit
ce571722d5
|
@ -31,6 +31,7 @@ public interface TaskCommentMapper {
|
|||
"<script> SELECT ID, TASK_ID, TEXT_FIELD, CREATOR, CREATED, MODIFIED"
|
||||
+ " FROM TASK_COMMENT "
|
||||
+ "WHERE TASK_ID = #{taskId} "
|
||||
+ " ORDER BY CREATED ASC "
|
||||
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
|
||||
+ "</script>")
|
||||
@Results(
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
-- TASK_COMMENT TABLE ID , TASK_ID ,TEXTFIELD ,CREATOR ,COMPLETED ,MODIFIED
|
||||
|
||||
-- TaskComments for GetTaskCommentAccTest + UpdateTaskCommentAccTest
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000000', 'TKI:000000000000000000000000000000000000', 'some text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000001', 'TKI:000000000000000000000000000000000000', 'some other text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000002', 'TKI:000000000000000000000000000000000000', 'some other text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000003', 'TKI:000000000000000000000000000000000025', 'some text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
||||
-- TaskComments for DeleteTaskCommentAccTest
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000004', 'TKI:000000000000000000000000000000000001', 'some text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000005', 'TKI:000000000000000000000000000000000001', 'some other text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000006', 'TKI:000000000000000000000000000000000002', 'some text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000007', 'TKI:000000000000000000000000000000000002', 'some other text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
||||
-- TaskComments for CreateTaskCommentAccTest
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000008', 'TKI:000000000000000000000000000000000026', 'some text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000009', 'TKI:000000000000000000000000000000000026', 'some other text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000010', 'TKI:000000000000000000000000000000000027', 'some text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000011', 'TKI:000000000000000000000000000000000027', 'some other text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
||||
INSERT INTO TASK_COMMENT VALUES('TCI:000000000000000000000000000000000012', 'TKI:000000000000000000000000000000000004', 'some text in textfield', 'user_1_1', '2018-01-29 15:55:00', '2018-01-30 15:55:00');
|
|
@ -25,6 +25,8 @@ public final class Mapping {
|
|||
public static final String URL_VERSION = PRE + "version";
|
||||
public static final String URL_TASKS = PRE + "tasks";
|
||||
public static final String URL_TASKS_ID = URL_TASKS + "/{taskId}";
|
||||
public static final String URL_TASK_COMMENTS = URL_TASKS_ID + "/comments";
|
||||
public static final String URL_TASK_COMMENT = URL_TASK_COMMENTS + "/{taskCommentId}";
|
||||
public static final String URL_TASKS_ID_CLAIM = URL_TASKS_ID + "/claim";
|
||||
public static final String URL_TASKS_ID_COMPLETE = URL_TASKS_ID + "/complete";
|
||||
public static final String URL_TASKS_ID_TRANSFER_WORKBASKETID =
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
package pro.taskana.rest;
|
||||
|
||||
import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import pro.taskana.common.api.exceptions.ConcurrencyException;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.rest.resource.TaskCommentListResource;
|
||||
import pro.taskana.rest.resource.TaskCommentResource;
|
||||
import pro.taskana.rest.resource.TaskCommentResourceAssembler;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.task.api.exceptions.TaskCommentNotFoundException;
|
||||
import pro.taskana.task.api.exceptions.TaskNotFoundException;
|
||||
import pro.taskana.task.api.models.TaskComment;
|
||||
|
||||
/** Controller for all {@link TaskComment} related endpoints. */
|
||||
@RestController
|
||||
@EnableHypermediaSupport(type = HypermediaType.HAL)
|
||||
public class TaskCommentController {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TaskCommentController.class);
|
||||
|
||||
private TaskService taskService;
|
||||
private TaskCommentResourceAssembler taskCommentResourceAssembler;
|
||||
|
||||
TaskCommentController(
|
||||
TaskService taskService, TaskCommentResourceAssembler taskCommentResourceAssembler) {
|
||||
this.taskService = taskService;
|
||||
this.taskCommentResourceAssembler = taskCommentResourceAssembler;
|
||||
}
|
||||
|
||||
|
||||
@GetMapping(path = Mapping.URL_TASK_COMMENT)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<TaskCommentResource> getTaskComment(@PathVariable String taskCommentId)
|
||||
throws NotAuthorizedException, TaskNotFoundException, TaskCommentNotFoundException,
|
||||
InvalidArgumentException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to getTaskComment(taskCommentId= {})", taskCommentId);
|
||||
}
|
||||
|
||||
TaskComment taskComment = taskService.getTaskComment(taskCommentId);
|
||||
|
||||
TaskCommentResource taskCommentResource = taskCommentResourceAssembler.toResource(taskComment);
|
||||
|
||||
ResponseEntity<TaskCommentResource> response = ResponseEntity.ok(taskCommentResource);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from getTaskComment(), returning {}", response);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@GetMapping(path = Mapping.URL_TASK_COMMENTS)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<TaskCommentListResource> getTaskComments(@PathVariable String taskId)
|
||||
throws NotAuthorizedException, TaskNotFoundException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to getTaskComments(taskId= {})", taskId);
|
||||
}
|
||||
|
||||
List<TaskComment> taskComments = taskService.getTaskComments(taskId);
|
||||
|
||||
TaskCommentListResource taskCommentListResource =
|
||||
taskCommentResourceAssembler.toListResource(taskComments);
|
||||
|
||||
ResponseEntity<TaskCommentListResource> response = ResponseEntity.ok(taskCommentListResource);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from getTaskComments(), returning {}", response);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@DeleteMapping(path = Mapping.URL_TASK_COMMENT)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<TaskCommentResource> deleteTaskComment(@PathVariable String taskCommentId)
|
||||
throws NotAuthorizedException, TaskNotFoundException, TaskCommentNotFoundException,
|
||||
InvalidArgumentException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to deleteTaskComment(taskCommentId= {})", taskCommentId);
|
||||
}
|
||||
|
||||
taskService.deleteTaskComment(taskCommentId);
|
||||
|
||||
ResponseEntity<TaskCommentResource> result = ResponseEntity.noContent().build();
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from deleteTaskComment(), returning {}", result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@PutMapping(path = Mapping.URL_TASK_COMMENT)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<TaskCommentResource> updateTaskComment(
|
||||
@PathVariable String taskCommentId, @RequestBody TaskCommentResource taskCommentResource)
|
||||
throws NotAuthorizedException, TaskNotFoundException, TaskCommentNotFoundException,
|
||||
InvalidArgumentException, ConcurrencyException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to updateTaskComment(taskCommentId= {})", taskCommentId);
|
||||
}
|
||||
|
||||
ResponseEntity<TaskCommentResource> result;
|
||||
if (taskCommentId.equals(taskCommentResource.getTaskCommentId())) {
|
||||
TaskComment taskComment = taskCommentResourceAssembler.toModel(taskCommentResource);
|
||||
|
||||
taskComment = taskService.updateTaskComment(taskComment);
|
||||
result = ResponseEntity.ok(taskCommentResourceAssembler.toResource(taskComment));
|
||||
} else {
|
||||
throw new InvalidArgumentException(
|
||||
String.format(
|
||||
"TaskCommentId ('%s') is not identical with the taskCommentId of "
|
||||
+ "object in the payload which should be updated. ID=('%s')",
|
||||
taskCommentId, taskCommentResource.getTaskId()));
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from updateTaskComment(), returning {}", result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping(path = Mapping.URL_TASK_COMMENTS)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseEntity<TaskCommentResource> createTaskComment(
|
||||
@RequestBody TaskCommentResource taskCommentResource)
|
||||
throws NotAuthorizedException, InvalidArgumentException, TaskNotFoundException {
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to createTaskComment(taskCommentResource= {})", taskCommentResource);
|
||||
}
|
||||
|
||||
TaskComment taskCommentFromResource = taskCommentResourceAssembler.toModel(taskCommentResource);
|
||||
TaskComment createdTaskComment = taskService.createTaskComment(taskCommentFromResource);
|
||||
|
||||
ResponseEntity<TaskCommentResource> result =
|
||||
ResponseEntity.status(HttpStatus.CREATED)
|
||||
.body(taskCommentResourceAssembler.toResource(createdTaskComment));
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from createTaskComment(), returning {}", result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package pro.taskana.rest.resource;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.List;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
|
||||
/** Resource class for {@link TaskCommentResource} with Pagination. */
|
||||
public class TaskCommentListResource extends ResourceSupport {
|
||||
|
||||
private List<TaskCommentResource> content;
|
||||
|
||||
public TaskCommentListResource() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TaskCommentListResource(List<TaskCommentResource> taskCommentResources) {
|
||||
this.content = taskCommentResources;
|
||||
}
|
||||
|
||||
@JsonProperty("task comments")
|
||||
public List<TaskCommentResource> getContent() {
|
||||
return content;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package pro.taskana.rest.resource;
|
||||
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
|
||||
import pro.taskana.task.api.models.TaskComment;
|
||||
|
||||
/** Resource class for {@link TaskComment}. */
|
||||
public class TaskCommentResource extends ResourceSupport {
|
||||
|
||||
private String taskCommentId;
|
||||
private String taskId;
|
||||
private String textField;
|
||||
private String creator;
|
||||
private String created;
|
||||
private String modified;
|
||||
|
||||
public TaskCommentResource() {}
|
||||
|
||||
public TaskCommentResource(TaskComment taskComment) {
|
||||
this.taskCommentId = taskComment.getId();
|
||||
this.taskId = taskComment.getTaskId();
|
||||
this.textField = taskComment.getTextField();
|
||||
this.creator = taskComment.getCreator();
|
||||
this.created = taskComment.getCreated().toString();
|
||||
this.modified = taskComment.getModified().toString();
|
||||
}
|
||||
|
||||
public String getTaskCommentId() {
|
||||
return taskCommentId;
|
||||
}
|
||||
|
||||
public void setTaskCommentId(String id) {
|
||||
this.taskCommentId = id;
|
||||
}
|
||||
|
||||
public String getTaskId() {
|
||||
return taskId;
|
||||
}
|
||||
|
||||
public void setTaskId(String taskId) {
|
||||
this.taskId = taskId;
|
||||
}
|
||||
|
||||
public String getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
public void setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public String getTextField() {
|
||||
return textField;
|
||||
}
|
||||
|
||||
public void setTextField(String textField) {
|
||||
this.textField = textField;
|
||||
}
|
||||
|
||||
public String getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(String created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public void setModified(String modified) {
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TaskCommentResource [taskCommentId="
|
||||
+ taskCommentId
|
||||
+ ", taskId="
|
||||
+ taskId
|
||||
+ ", textField="
|
||||
+ textField
|
||||
+ ", creator="
|
||||
+ creator
|
||||
+ ", created="
|
||||
+ created
|
||||
+ ", modified="
|
||||
+ modified
|
||||
+ "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package pro.taskana.rest.resource;
|
||||
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.mvc.ResourceAssemblerSupport;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.api.exceptions.SystemException;
|
||||
import pro.taskana.rest.Mapping;
|
||||
import pro.taskana.rest.TaskCommentController;
|
||||
import pro.taskana.rest.resource.links.PageLinks;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.task.api.exceptions.TaskCommentNotFoundException;
|
||||
import pro.taskana.task.api.exceptions.TaskNotFoundException;
|
||||
import pro.taskana.task.api.models.TaskComment;
|
||||
import pro.taskana.task.internal.models.TaskCommentImpl;
|
||||
|
||||
/** Resource assembler for {@link TaskCommentResource}. */
|
||||
@Component
|
||||
public class TaskCommentResourceAssembler
|
||||
extends ResourceAssemblerSupport<TaskComment, TaskCommentResource> {
|
||||
|
||||
private final TaskService taskService;
|
||||
|
||||
@Autowired
|
||||
public TaskCommentResourceAssembler(TaskService taskService) {
|
||||
super(TaskCommentController.class, TaskCommentResource.class);
|
||||
this.taskService = taskService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskCommentResource toResource(TaskComment taskComment) {
|
||||
|
||||
TaskCommentResource taskCommentResource = new TaskCommentResource(taskComment);
|
||||
try {
|
||||
taskCommentResource.add(
|
||||
linkTo(methodOn(TaskCommentController.class).getTaskComment(taskComment.getId()))
|
||||
.withSelfRel());
|
||||
} catch (TaskCommentNotFoundException
|
||||
| TaskNotFoundException
|
||||
| NotAuthorizedException
|
||||
| InvalidArgumentException e) {
|
||||
throw new SystemException("caught unexpected Exception.", e.getCause());
|
||||
}
|
||||
|
||||
return taskCommentResource;
|
||||
}
|
||||
|
||||
@PageLinks(Mapping.URL_TASK_COMMENTS)
|
||||
public TaskCommentListResource toListResource(
|
||||
List<TaskComment> taskComments) {
|
||||
return new TaskCommentListResource(toResources(taskComments));
|
||||
}
|
||||
|
||||
public TaskComment toModel(TaskCommentResource taskCommentResource) {
|
||||
|
||||
TaskCommentImpl taskComment =
|
||||
(TaskCommentImpl) taskService.newTaskComment(taskCommentResource.getTaskId());
|
||||
taskComment.setId(taskCommentResource.getTaskCommentId());
|
||||
|
||||
BeanUtils.copyProperties(taskCommentResource, taskComment);
|
||||
|
||||
if (taskCommentResource.getCreated() != null) {
|
||||
taskComment.setCreated(Instant.parse(taskCommentResource.getCreated()));
|
||||
}
|
||||
if (taskCommentResource.getModified() != null) {
|
||||
taskComment.setModified(Instant.parse(taskCommentResource.getModified()));
|
||||
}
|
||||
|
||||
return taskComment;
|
||||
}
|
||||
}
|
|
@ -64,6 +64,13 @@ public class RestHelper {
|
|||
return headers;
|
||||
}
|
||||
|
||||
public HttpHeaders getHeadersUser_1_1() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("Authorization", "Basic dXNlcl8xXzE6dXNlcl8xXzE=");
|
||||
headers.add("Content-Type", "application/json");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a REST template which is capable of dealing with responses in HAL format.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
package pro.taskana.doc.api;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
|
||||
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
|
||||
import org.springframework.restdocs.payload.FieldDescriptor;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
||||
|
||||
import pro.taskana.rest.Mapping;
|
||||
|
||||
public class TaskCommentControllerRestDocumentation extends BaseRestDocumentation {
|
||||
|
||||
private HashMap<String, String> taskCommentFieldDescriptionsMap = new HashMap<String, String>();
|
||||
|
||||
private FieldDescriptor[] allTaskCommentsFieldDescriptors;
|
||||
private FieldDescriptor[] taskCommentFieldDescriptors;
|
||||
private FieldDescriptor[] createTaskCommentFieldDescriptors;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
taskCommentFieldDescriptionsMap.put("taskCommentId", "Unique ID");
|
||||
taskCommentFieldDescriptionsMap.put(
|
||||
"taskId", "Task ID. Can identify the task to which the comment belongs");
|
||||
taskCommentFieldDescriptionsMap.put("textField", "The content of the actual comment");
|
||||
taskCommentFieldDescriptionsMap.put("creator", "The creator of the task comment");
|
||||
taskCommentFieldDescriptionsMap.put(
|
||||
"created", "The creation timestamp of the task comment in the system.");
|
||||
taskCommentFieldDescriptionsMap.put(
|
||||
"modified", "Timestamp of the last modification of the task comment");
|
||||
|
||||
taskCommentFieldDescriptors =
|
||||
new FieldDescriptor[] {
|
||||
fieldWithPath("taskCommentId")
|
||||
.description(taskCommentFieldDescriptionsMap.get("taskCommentId")),
|
||||
fieldWithPath("taskId").description(taskCommentFieldDescriptionsMap.get("taskId")),
|
||||
fieldWithPath("textField").description(taskCommentFieldDescriptionsMap.get("textField")),
|
||||
fieldWithPath("creator").description(taskCommentFieldDescriptionsMap.get("creator")),
|
||||
fieldWithPath("created")
|
||||
.description(taskCommentFieldDescriptionsMap.get("created"))
|
||||
.type("String"),
|
||||
fieldWithPath("modified")
|
||||
.description(taskCommentFieldDescriptionsMap.get("modified"))
|
||||
.type("String"),
|
||||
fieldWithPath("_links").ignored(),
|
||||
fieldWithPath("_links.self").ignored(),
|
||||
fieldWithPath("_links.self.href").ignored(),
|
||||
fieldWithPath("_links.self.templated").ignored()
|
||||
};
|
||||
|
||||
createTaskCommentFieldDescriptors =
|
||||
new FieldDescriptor[] {
|
||||
fieldWithPath("taskId").description(taskCommentFieldDescriptionsMap.get("taskId")),
|
||||
fieldWithPath("textField").description(taskCommentFieldDescriptionsMap.get("textField")),
|
||||
fieldWithPath("creator")
|
||||
.description(taskCommentFieldDescriptionsMap.get("creator"))
|
||||
.type("String")
|
||||
.optional(),
|
||||
fieldWithPath("created")
|
||||
.description(taskCommentFieldDescriptionsMap.get("created"))
|
||||
.type("String")
|
||||
.optional(),
|
||||
fieldWithPath("modified")
|
||||
.description(taskCommentFieldDescriptionsMap.get("modified"))
|
||||
.type("String")
|
||||
.optional(),
|
||||
};
|
||||
|
||||
allTaskCommentsFieldDescriptors =
|
||||
new FieldDescriptor[] {
|
||||
subsectionWithPath("task comments")
|
||||
.description("An Array of task comments")
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAllTaskCommentsForSpecificTaskDocTest() throws Exception {
|
||||
this.mockMvc
|
||||
.perform(
|
||||
RestDocumentationRequestBuilders.get(
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_TASK_COMMENTS, "TKI:000000000000000000000000000000000000"))
|
||||
.accept("application/hal+json")
|
||||
.header("Authorization", "Basic YWRtaW46YWRtaW4="))
|
||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||
.andDo(
|
||||
MockMvcRestDocumentation.document(
|
||||
"GetAllTaskCommentsForSpecificTaskDocTest",
|
||||
responseFields(allTaskCommentsFieldDescriptors)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSpecificTaskCommentDocTest() throws Exception {
|
||||
this.mockMvc
|
||||
.perform(
|
||||
RestDocumentationRequestBuilders.get(
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_TASK_COMMENT,
|
||||
"TKI:100000000000000000000000000000000000",
|
||||
"TCI:000000000000000000000000000000000000"))
|
||||
.accept("application/hal+json")
|
||||
.header("Authorization", "Basic YWRtaW46YWRtaW4="))
|
||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||
.andDo(
|
||||
MockMvcRestDocumentation.document(
|
||||
"GetSpecificTaskCommentDocTest", responseFields(taskCommentFieldDescriptors)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateTaskCommentDocTest() throws Exception {
|
||||
URL url =
|
||||
new URL(
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_TASK_COMMENT,
|
||||
"TKI:000000000000000000000000000000000000",
|
||||
"TCI:000000000000000000000000000000000000"));
|
||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||
con.setRequestMethod("GET");
|
||||
con.setRequestProperty("Authorization", "Basic YWRtaW46YWRtaW4=");
|
||||
assertEquals(200, con.getResponseCode());
|
||||
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream(), UTF_8));
|
||||
String inputLine;
|
||||
StringBuilder content = new StringBuilder();
|
||||
while ((inputLine = in.readLine()) != null) {
|
||||
content.append(inputLine);
|
||||
}
|
||||
in.close();
|
||||
con.disconnect();
|
||||
String originalTaskComment = content.toString();
|
||||
String modifiedTaskComment =
|
||||
originalTaskComment.replace("some text in textfield", "updated text in textfield");
|
||||
|
||||
this.mockMvc
|
||||
.perform(
|
||||
RestDocumentationRequestBuilders.put(
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_TASK_COMMENT,
|
||||
"TKI:000000000000000000000000000000000000",
|
||||
"TCI:000000000000000000000000000000000000"))
|
||||
.header("Authorization", "Basic YWRtaW46YWRtaW4=")
|
||||
.contentType("application/json")
|
||||
.content(modifiedTaskComment))
|
||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||
.andDo(
|
||||
MockMvcRestDocumentation.document(
|
||||
"UpdateTaskCommentDocTest",
|
||||
requestFields(taskCommentFieldDescriptors),
|
||||
responseFields(taskCommentFieldDescriptors)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createAndDeleteTaskCommentDocTest() throws Exception {
|
||||
|
||||
MvcResult result =
|
||||
this.mockMvc
|
||||
.perform(
|
||||
RestDocumentationRequestBuilders.post(
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_TASK_COMMENTS, "TKI:000000000000000000000000000000000000"))
|
||||
.contentType("application/hal+json")
|
||||
.content(
|
||||
"{ \"taskId\" : \"TKI:000000000000000000000000000000000000\",\n"
|
||||
+ " \"textField\" : \"some text in textfield\"} ")
|
||||
.header("Authorization", "Basic YWRtaW46YWRtaW4="))
|
||||
.andExpect(MockMvcResultMatchers.status().isCreated())
|
||||
.andDo(
|
||||
MockMvcRestDocumentation.document(
|
||||
"CreateTaskCommentDocTest",
|
||||
requestFields(createTaskCommentFieldDescriptors),
|
||||
responseFields(taskCommentFieldDescriptors)))
|
||||
.andReturn();
|
||||
|
||||
String content = result.getResponse().getContentAsString();
|
||||
String newId = content.substring(content.indexOf("TCI:"), content.indexOf("TCI:") + 40);
|
||||
|
||||
this.mockMvc
|
||||
.perform(
|
||||
RestDocumentationRequestBuilders.delete(
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_TASK_COMMENT,
|
||||
"TKI:000000000000000000000000000000000000",
|
||||
newId))
|
||||
.header("Authorization", "Basic YWRtaW46YWRtaW4=")) // admin
|
||||
.andExpect(MockMvcResultMatchers.status().isNoContent())
|
||||
.andDo(MockMvcRestDocumentation.document("DeleteTaskCommentDocTest"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
package pro.taskana.rest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import pro.taskana.RestHelper;
|
||||
import pro.taskana.TaskanaSpringBootTest;
|
||||
import pro.taskana.rest.resource.TaskCommentListResource;
|
||||
import pro.taskana.rest.resource.TaskCommentResource;
|
||||
|
||||
/** Test TaskCommentController. */
|
||||
@TaskanaSpringBootTest
|
||||
class TaskCommentControllerIntTest {
|
||||
|
||||
private static RestTemplate template;
|
||||
|
||||
@Value("${taskana.schemaName:TASKANA}")
|
||||
public String schemaName;
|
||||
|
||||
@Autowired RestHelper restHelper;
|
||||
|
||||
@BeforeAll
|
||||
static void init() {
|
||||
template = RestHelper.TEMPLATE;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetNonExistentCommentShouldFail() {
|
||||
|
||||
String urlToNonExistingTaskComment =
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_TASK_COMMENT,
|
||||
"TKI:000000000000000000000000000000000000",
|
||||
"Non existing task comment Id");
|
||||
|
||||
assertThatThrownBy(
|
||||
() ->
|
||||
template.exchange(
|
||||
urlToNonExistingTaskComment,
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<String>(restHelper.getHeadersAdmin()),
|
||||
ParameterizedTypeReference.forType(TaskCommentResource.class)))
|
||||
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
|
||||
.isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetCommentsForNonExistingTaskShouldFail() {
|
||||
|
||||
String urlToNonExistingTask = restHelper.toUrl(Mapping.URL_TASK_COMMENTS, "nonExistingTaskId");
|
||||
|
||||
assertThatThrownBy(
|
||||
() ->
|
||||
template.exchange(
|
||||
urlToNonExistingTask,
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<String>(restHelper.getHeadersAdmin()),
|
||||
ParameterizedTypeReference.forType(TaskCommentListResource.class)))
|
||||
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
|
||||
.isEqualTo(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
@Disabled("Disabled until Authorization check is up!")
|
||||
@Test
|
||||
void testGetTaskCommentsOfNotVisibleTaskShouldFail() {
|
||||
|
||||
String urlToNotVisibleTask =
|
||||
restHelper.toUrl(Mapping.URL_TASK_COMMENTS, "TKI:000000000000000000000000000000000004");
|
||||
|
||||
ResponseEntity<TaskCommentListResource> response =
|
||||
template.exchange(
|
||||
urlToNotVisibleTask,
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<String>(restHelper.getHeadersUser_1_1()),
|
||||
ParameterizedTypeReference.forType(TaskCommentListResource.class));
|
||||
}
|
||||
|
||||
@Disabled("Disabled until Authorization check is up!")
|
||||
@Test
|
||||
void testGetTaskCommentOfNotVisibleTaskShouldFail() {
|
||||
|
||||
String urlToNotVisibleTask =
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_TASK_COMMENT,
|
||||
"TKI:000000000000000000000000000000000004",
|
||||
"TCI:000000000000000000000000000000000013");
|
||||
|
||||
ResponseEntity<TaskCommentResource> response =
|
||||
template.exchange(
|
||||
urlToNotVisibleTask,
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<String>(restHelper.getHeadersUser_1_1()),
|
||||
ParameterizedTypeReference.forType(TaskCommentResource.class));
|
||||
}
|
||||
|
||||
@Disabled("Disabled until Authorization check is up!")
|
||||
@Test
|
||||
void testCreateTaskCommentForNotVisibleTaskShouldFail() {
|
||||
|
||||
TaskCommentResource taskCommentResourceToCreate = new TaskCommentResource();
|
||||
taskCommentResourceToCreate.setTaskId("TKI:000000000000000000000000000000000004");
|
||||
taskCommentResourceToCreate.setTextField("newly created task comment");
|
||||
|
||||
assertThatThrownBy(
|
||||
() ->
|
||||
template.exchange(
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_TASK_COMMENTS, "TKI:000000000000000000000000000000000004"),
|
||||
HttpMethod.POST,
|
||||
new HttpEntity<>(taskCommentResourceToCreate, restHelper.getHeadersUser_1_1()),
|
||||
ParameterizedTypeReference.forType(TaskCommentResource.class)))
|
||||
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
|
||||
.isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateTaskCommentForNotExistingTaskShouldFail() {
|
||||
|
||||
TaskCommentResource taskCommentResourceToCreate = new TaskCommentResource();
|
||||
taskCommentResourceToCreate.setTaskId("DefinatelyNotExistingId");
|
||||
taskCommentResourceToCreate.setTextField("newly created task comment");
|
||||
|
||||
assertThatThrownBy(
|
||||
() ->
|
||||
template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASK_COMMENTS, "NotExistingTaskId"),
|
||||
HttpMethod.POST,
|
||||
new HttpEntity<>(taskCommentResourceToCreate, restHelper.getHeadersUser_1_1()),
|
||||
ParameterizedTypeReference.forType(TaskCommentResource.class)))
|
||||
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
|
||||
.isEqualTo(HttpStatus.NOT_FOUND);
|
||||
|
||||
TaskCommentResource taskCommentResourceToCreate2 = new TaskCommentResource();
|
||||
taskCommentResourceToCreate.setTaskId(null);
|
||||
taskCommentResourceToCreate.setTextField("newly created task comment");
|
||||
|
||||
assertThatThrownBy(
|
||||
() ->
|
||||
template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASK_COMMENTS, "NotExistingTaskId"),
|
||||
HttpMethod.POST,
|
||||
new HttpEntity<>(taskCommentResourceToCreate2, restHelper.getHeadersUser_1_1()),
|
||||
ParameterizedTypeReference.forType(TaskCommentResource.class)))
|
||||
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
|
||||
.isEqualTo(HttpStatus.NOT_FOUND);
|
||||
|
||||
TaskCommentResource taskCommentResourceToCreate3 = new TaskCommentResource();
|
||||
taskCommentResourceToCreate.setTaskId("");
|
||||
taskCommentResourceToCreate.setTextField("newly created task comment");
|
||||
|
||||
assertThatThrownBy(
|
||||
() ->
|
||||
template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASK_COMMENTS, "NotExistingTaskId"),
|
||||
HttpMethod.POST,
|
||||
new HttpEntity<>(taskCommentResourceToCreate3, restHelper.getHeadersUser_1_1()),
|
||||
ParameterizedTypeReference.forType(TaskCommentResource.class)))
|
||||
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
|
||||
.isEqualTo(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateTaskCommentWithConcurrentModificationShouldFail() {}
|
||||
|
||||
@Test
|
||||
void testUpdateTaskCommentWithNoAuthorizationShouldFail() {}
|
||||
|
||||
@Test
|
||||
void testUpdateTaskCommentOfNotExistingTaskShouldFail() {}
|
||||
}
|
|
@ -293,6 +293,97 @@ include::{snippets}/TransferTaskDocTest/http-response.adoc[]
|
|||
The response-body is essentially the same as for getting a single task. +
|
||||
Therefore for the response fields you can refer to the <<task, single task>>.
|
||||
|
||||
== TaskComment-Resource
|
||||
|
||||
=== Get a list of all task comments for a specific task
|
||||
|
||||
A `GET` request is used to retrieve the task comments.
|
||||
|
||||
==== Example Request
|
||||
|
||||
include::{snippets}/GetAllTaskCommentsForSpecificTaskDocTest/http-request.adoc[]
|
||||
|
||||
==== Example Response
|
||||
|
||||
include::{snippets}/GetAllTaskCommentsForSpecificTaskDocTest/http-response.adoc[]
|
||||
|
||||
==== Response Structure
|
||||
|
||||
include::{snippets}/GetAllTaskCommentsForSpecificTaskDocTest/response-fields.adoc[]
|
||||
|
||||
|
||||
=== Get a specific task comment
|
||||
|
||||
A `GET` request is used to retrieve a task comment.
|
||||
|
||||
==== Example Request
|
||||
|
||||
include::{snippets}/GetSpecificTaskCommentDocTest/http-request.adoc[]
|
||||
|
||||
==== Example Response
|
||||
|
||||
include::{snippets}/GetSpecificTaskCommentDocTest/http-response.adoc[]
|
||||
|
||||
==== Response Structure
|
||||
|
||||
include::{snippets}/GetSpecificTaskCommentDocTest/response-fields.adoc[]
|
||||
|
||||
=== Update a task comment
|
||||
|
||||
A `PUT` request is used to update a task comment.
|
||||
|
||||
==== Example Request
|
||||
|
||||
include::{snippets}/UpdateTaskCommentDocTest/http-request.adoc[]
|
||||
|
||||
==== Request Structure
|
||||
|
||||
include::{snippets}/UpdateTaskCommentDocTest/request-fields.adoc[]
|
||||
|
||||
==== Example Response
|
||||
|
||||
include::{snippets}/UpdateTaskCommentDocTest/http-response.adoc[]
|
||||
|
||||
==== Response Structure
|
||||
|
||||
include::{snippets}/UpdateTaskCommentDocTest/response-fields.adoc[]
|
||||
|
||||
=== Create a new task comment
|
||||
|
||||
A `POST` request is used to create a new task comment.
|
||||
|
||||
==== Example Request
|
||||
|
||||
This minimal example shows only the required fields to create a new task comment. The <<create-task-comment-request-structure, request structure>> shows all possible fields for creating a task comment.
|
||||
|
||||
include::{snippets}/CreateTaskCommentDocTest/http-request.adoc[]
|
||||
|
||||
[[create-taskcomment--request-structure, request structure]]
|
||||
==== Request Structure
|
||||
|
||||
include::{snippets}/CreateTaskCommentDocTest/request-fields.adoc[]
|
||||
|
||||
==== Example Response
|
||||
|
||||
include::{snippets}/CreateTaskCommentDocTest/http-response.adoc[]
|
||||
|
||||
==== Response Structure
|
||||
|
||||
The response-body is essentially the same as for getting a specific task comment. +
|
||||
Therefore for the response fields you can refer to the <<task comment, specific task comment>>.
|
||||
|
||||
=== Delete a task comment
|
||||
|
||||
A `DELETE` request is used to delete a task comment.
|
||||
|
||||
==== Example request
|
||||
|
||||
include::{snippets}/DeleteTaskCommentDocTest/http-request.adoc[]
|
||||
|
||||
==== Example response
|
||||
|
||||
include::{snippets}/DeleteTaskCommentDocTest/http-response.adoc[]
|
||||
|
||||
== Classifications-Resource
|
||||
|
||||
This resource provides the entry point with classifications.
|
||||
|
|
Loading…
Reference in New Issue