From 4ca0ae869fe8c7fc8478ab72593b33d50912839c Mon Sep 17 00:00:00 2001 From: CRoberto1926 <3205022+CRoberto1926@users.noreply.github.com> Date: Thu, 25 Jul 2024 13:12:09 +0200 Subject: [PATCH] Closes #2635: Make owner-is-null=owner-is-null not valid, allow use case "owner-is-null=true" --- .../rest/util/QueryParamsValidator.java | 67 ++++++++++---- .../pro/taskana/task/rest/TaskController.java | 25 ++++-- .../task/rest/TaskQueryFilterParameter.java | 43 ++++++++- .../pro/taskana/user/rest/UserController.java | 18 ++-- .../task/rest/TaskControllerIntTest.java | 66 +++++++------- .../user/rest/UserControllerIntTest.java | 90 +++++++++---------- 6 files changed, 199 insertions(+), 110 deletions(-) diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/util/QueryParamsValidator.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/util/QueryParamsValidator.java index 10b7b0726a..a1a33d4eb0 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/util/QueryParamsValidator.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/util/QueryParamsValidator.java @@ -1,15 +1,14 @@ package pro.taskana.common.rest.util; import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Arrays; import java.util.HashSet; +import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.servlet.http.HttpServletRequest; -import pro.taskana.common.api.exceptions.InvalidArgumentException; public class QueryParamsValidator { @@ -35,21 +34,57 @@ public static void validateParams(HttpServletRequest request, Class... filter if (!providedParams.isEmpty()) { throw new IllegalArgumentException("Unknown request parameters found: " + providedParams); } - checkExactParam(request, "owner-is-null"); } - public static void checkExactParam(HttpServletRequest request, String queryParameter) { - String queryString = request.getQueryString(); - boolean containParam = queryString != null && queryString.contains(queryParameter); - if (containParam) { - Pattern pattern = Pattern.compile("\\b" + queryParameter + "(&|$)"); - Matcher matcher = pattern.matcher(queryString); - - boolean hasExactParam = matcher.find(); - if (!hasExactParam) { - throw new InvalidArgumentException( - "It is prohibited to use the param " + queryParameter + " with values."); - } + public static boolean hasQueryParameterValues(HttpServletRequest request, String queryParameter) { + + Map queryParametersMap = request.getParameterMap(); + + if (queryParametersMap.isEmpty()) { + return false; + } + + String[] queryParameterValues = queryParametersMap.get(queryParameter); + + if (queryParameterValues == null) { + return false; } + + boolean hasQueryParameterNotEmptyValues = + Arrays.stream(queryParameterValues).anyMatch(value -> !value.isBlank()); + + /* Workaround to manage the case "query-param=". + It should be safe enough to use because we have checked all other possibilities before. */ + boolean hasQueryParameterEmptyValues = request.getQueryString().contains(queryParameter + "="); + + return hasQueryParameterNotEmptyValues || hasQueryParameterEmptyValues; + } + + public static boolean hasQueryParameterValuesOrIsNotTrue( + HttpServletRequest request, String queryParameter) { + + Map queryParametersMap = request.getParameterMap(); + + if (queryParametersMap.isEmpty()) { + return false; + } + + String[] queryParameterValues = queryParametersMap.get(queryParameter); + + if (queryParameterValues == null) { + return false; + } + + boolean hasQueryParameterProhibitedValues = + Arrays.stream(queryParameterValues) + .anyMatch(value -> !value.isBlank() && !Boolean.parseBoolean(value)); + + /* Workaround to manage the case "query-param=". + It should be safe enough to use because we have checked all other possibilities before. */ + boolean hasQueryParameterEmptyValues = + Arrays.stream(queryParameterValues).allMatch(String::isBlank) + && request.getQueryString().contains(queryParameter + "="); + + return hasQueryParameterProhibitedValues || hasQueryParameterEmptyValues; } } diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java index e4122b4612..91fad73913 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java @@ -118,11 +118,12 @@ public ResponseEntity createTask( NotAuthorizedOnWorkbasketException { if (!taskRepresentationModel.getAttachments().stream() - .filter(att -> Objects.nonNull(att.getTaskId())) - .filter(att -> !att.getTaskId().equals(taskRepresentationModel.getTaskId())) - .collect(Collectors.toList()).isEmpty()) { + .filter(att -> Objects.nonNull(att.getTaskId())) + .filter(att -> !att.getTaskId().equals(taskRepresentationModel.getTaskId())) + .collect(Collectors.toList()) + .isEmpty()) { throw new InvalidArgumentException( - "An attachments' taskId must be empty or equal to the id of the task it belongs to"); + "An attachments' taskId must be empty or equal to the id of the task it belongs to"); } Task fromResource = taskRepresentationModelAssembler.toEntityModel(taskRepresentationModel); @@ -148,6 +149,7 @@ public ResponseEntity createTask( * @param sortParameter the sort parameters * @param pagingParameter the paging parameters * @return the Tasks with the given filter, sort and paging options. + * @throws InvalidArgumentException if the query parameter "owner-is-null" has values */ @GetMapping(path = RestEndpoints.URL_TASKS) @Transactional(readOnly = true, rollbackFor = Exception.class) @@ -167,6 +169,12 @@ public ResponseEntity getTasks( TaskQueryGroupByParameter.class, QuerySortParameter.class, QueryPagingParameter.class); + + if (QueryParamsValidator.hasQueryParameterValuesOrIsNotTrue(request, "owner-is-null")) { + throw new InvalidArgumentException( + "It is prohibited to use the param owner-is-null with values."); + } + TaskQuery query = taskService.createTaskQuery(); filterParameter.apply(query); @@ -653,11 +661,12 @@ public ResponseEntity updateTask( } if (!taskRepresentationModel.getAttachments().stream() - .filter(att -> Objects.nonNull(att.getTaskId())) - .filter(att -> !att.getTaskId().equals(taskRepresentationModel.getTaskId())) - .collect(Collectors.toList()).isEmpty()) { + .filter(att -> Objects.nonNull(att.getTaskId())) + .filter(att -> !att.getTaskId().equals(taskRepresentationModel.getTaskId())) + .collect(Collectors.toList()) + .isEmpty()) { throw new InvalidArgumentException( - "An attachments' taskId must be empty or equal to the id of the task it belongs to"); + "An attachments' taskId must be empty or equal to the id of the task it belongs to"); } Task task = taskRepresentationModelAssembler.toEntityModel(taskRepresentationModel); diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskQueryFilterParameter.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskQueryFilterParameter.java index 9b60b42077..c9640fbc34 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskQueryFilterParameter.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskQueryFilterParameter.java @@ -28,6 +28,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by what the task id shouldn't be. This is an exact match. */ @JsonProperty("task-id-not") private final String[] taskIdNotIn; + // endregion // region externalId /** Filter by the external id of the Task. This is an exact match. */ @@ -37,6 +38,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by what the external id of the Task shouldn't be. This is an exact match. */ @JsonProperty("external-id-not") private final String[] externalIdNotIn; + // endregion // region received /** @@ -101,6 +103,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("received-until-not") private final Instant receivedUntilNot; + // endregion // region created /** @@ -164,6 +167,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("created-until-not") private final Instant createdUntilNot; + // endregion // region claimed /** @@ -183,6 +187,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("claimed-not") private final Instant[] claimedNotWithin; + // endregion // region modified /** @@ -202,6 +207,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("modified-not") private final Instant[] modifiedNotWithin; + // endregion // region planned /** @@ -265,6 +271,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("planned-until-not") private final Instant plannedUntilNot; + // endregion // region due /** @@ -328,6 +335,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("due-until-not") private final Instant dueUntilNot; + // endregion // region completed /** @@ -392,6 +400,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("completed-until-not") private final Instant completedUntilNot; + // endregion // region name /** Filter by the name of the Task. This is an exact match. */ @@ -417,6 +426,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("name-not-like") private final String[] nameNotLike; + // endregion // region creator /** Filter by creator of the Task. This is an exact match. */ @@ -442,6 +452,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("creator-not-like") private final String[] creatorNotLike; + // endregion // region note /** @@ -459,6 +470,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("note-not-like") private final String[] noteNotLike; + // endregion // region description /** @@ -476,6 +488,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("description-not-like") private final String[] descriptionNotLike; + // endregion // region priority /** Filter by the priority of the Task. This is an exact match. */ @@ -509,6 +522,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by excluding priority up to the given value (inclusive). */ @JsonProperty("priority-not-until") private final Integer priorityNotUntil; + // endregion // region state /** Filter by the Task state. This is an exact match. */ @@ -518,6 +532,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by what the Task state shouldn't be. This is an exact match. */ @JsonProperty("state-not") private final TaskState[] stateNotIn; + // endregion // region comments /** Filter by the has comments flag of the Task. This is an exact match. */ @@ -532,6 +547,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by what the classification id of the Task shouldn't be. This is an exact match. */ @JsonProperty("classification-id-not") private final String[] classificationIdNotIn; + // endregion // region classificationKey /** Filter by the classification key of the Task. This is an exact match. */ @@ -557,6 +573,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("classification-key-not-like") private final String[] classificationKeyNotLike; + // endregion // region classificationParentKey /** @@ -588,6 +605,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("classification-parent-key-not-like") private final String[] classificationParentKeyNotLike; + // endregion // region classificationCategory /** Filter by the classification category of the Task. This is an exact match. */ @@ -615,6 +633,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("classification-category-not-like") private final String[] classificationCategoryNotLike; + // endregion // region classificationName /** Filter by the classification name of the Task. This is an exact match. */ @@ -640,6 +659,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("classification-name-not-like") private final String[] classificationNameNotLike; + // endregion // region workbasketId /** Filter by workbasket id of the Task. This is an exact match. */ @@ -649,6 +669,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by what the workbasket id of the Task shouldn't be. This is an exact match. */ @JsonProperty("workbasket-id-not") private final String[] workbasketIdNotIn; + // endregion // region workbasketKeyDomain /** @@ -668,6 +689,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by domain of the Task. This is an exact match. */ @JsonProperty("domain") private final String domain; + // endregion // region businessProcessId /** Filter by the business process id of the Task. This is an exact match. */ @@ -754,6 +776,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("owner-is-null") private final String ownerNull; + // endregion // region primaryObjectReference /** @@ -764,6 +787,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("por") private final ObjectReference[] primaryObjectReferenceIn; + // endregion // region primaryObjectReferenceCompany /** Filter by the company of the primary object reference of the Task. This is an exact match. */ @@ -792,6 +816,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("por-company-not-like") private final String[] porCompanyNotLike; + // endregion // region primaryObjectReferenceSystem /** Filter by the system of the primary object reference of the Task. This is an exact match. */ @@ -820,6 +845,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("por-system-not-like") private final String[] porSystemNotLike; + // endregion // region primaryObjectReferenceSystemInstance /** @@ -851,6 +877,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("por-instance-not-like") private final String[] porInstanceNotLike; + // endregion // region primaryObjectReferenceSystemType /** Filter by the type of the primary object reference of the Task. This is an exact match. */ @@ -879,6 +906,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("por-type-not-like") private final String[] porTypeNotLike; + // endregion // region primaryObjectReferenceSystemValue /** Filter by the value of the primary object reference of the Task. This is an exact match. */ @@ -907,6 +935,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("por-value-not-like") private final String[] porValueNotLike; + // endregion // region secondaryObjectReference /** @@ -917,6 +946,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("sor") private final ObjectReference[] secondaryObjectReferenceIn; + // endregion // region secondaryObjectReferenceCompany /** @@ -997,11 +1027,13 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by the is read flag of the Task. This is an exact match. */ @JsonProperty("is-read") private final Boolean isRead; + // endregion // region transferred /** Filter by the is transferred flag of the Task. This is an exact match. */ @JsonProperty("is-transferred") private final Boolean isTransferred; + // endregion // region attachmentClassificationId /** Filter by the attachment classification id of the Task. This is an exact match. */ @@ -1014,6 +1046,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("attachment-classification-id-not") private final String[] attachmentClassificationIdNotIn; + // endregion // region attachmentClassificationKey /** Filter by the attachment classification key of the Task. This is an exact match. */ @@ -1042,6 +1075,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("attachment-classification-key-not-like") private final String[] attachmentClassificationKeyNotLike; + // endregion // region attachmentClassificationName /** Filter by the attachment classification name of the Task. This is an exact match. */ @@ -1070,6 +1104,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("attachment-classification-name-not-like") private final String[] attachmentClassificationNameNotLike; + // endregion // region attachmentChannel /** Filter by the attachment channel of the Task. This is an exact match. */ @@ -1095,6 +1130,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("attachment-channel-not-like") private final String[] attachmentChannelNotLike; + // endregion // region attachmentReferenceValue /** Filter by the attachment reference of the Task. This is an exact match. */ @@ -1120,6 +1156,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("attachment-reference-not-like") private final String[] attachmentReferenceNotLike; + // endregion // region attachmentReceived /** @@ -1139,6 +1176,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("attachment-received-not") private final Instant[] attachmentReceivedNotWithin; + // endregion // region withoutAttachment /** @@ -1147,6 +1185,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("without-attachment") private final Boolean withoutAttachment; + // endregion // region callbackState /** Filter by the callback state of the Task. This is an exact match. */ @@ -1156,6 +1195,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by what the callback state of the Task shouldn't be. This is an exact match. */ @JsonProperty("callback-state-not") private final CallbackState[] callbackStateNotIn; + // endregion // region wildcardSearchValue /** @@ -1173,6 +1213,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("wildcard-search-value") private final String wildcardSearchValue; + // endregion // region constructor @@ -2213,7 +2254,7 @@ private String[] addNullToOwnerIn() { return this.ownerIn; } if (this.ownerIn == null) { - return new String[]{null}; + return new String[] {null}; } List ownerInAsList = new ArrayList<>(Arrays.asList(this.ownerIn)); ownerInAsList.add(null); diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/user/rest/UserController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/user/rest/UserController.java index d82dc52ad5..00544b8837 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/user/rest/UserController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/user/rest/UserController.java @@ -41,9 +41,10 @@ public class UserController { private final CurrentUserContext currentUserContext; @Autowired - UserController(UserService userService, - UserRepresentationModelAssembler userAssembler, - CurrentUserContext currentUserContext) { + UserController( + UserService userService, + UserRepresentationModelAssembler userAssembler, + CurrentUserContext currentUserContext) { this.userService = userService; this.userAssembler = userAssembler; this.currentUserContext = currentUserContext; @@ -68,8 +69,8 @@ public ResponseEntity getUser(@PathVariable String user /** * This endpoint retrieves multiple Users. If a userId can't be found in the database it will be - * ignored. If none of the given userIds is valid, the returned list will be empty. - * If currentUser is set, the current User from the context will be retrieved as well + * ignored. If none of the given userIds is valid, the returned list will be empty. If currentUser + * is set, the current User from the context will be retrieved as well * * @title Get multiple Users * @param request the HttpServletRequest of the request itself @@ -85,7 +86,7 @@ public ResponseEntity getUsers( HttpServletRequest request, @RequestParam(name = "user-id", required = false) String[] userIds, @RequestParam(name = "current-user", required = false) String currentUser) - throws InvalidArgumentException, UserNotFoundException { + throws InvalidArgumentException, UserNotFoundException { Set users = new HashSet<>(); if (userIds != null) { @@ -93,7 +94,10 @@ public ResponseEntity getUsers( } if (currentUser != null) { - QueryParamsValidator.checkExactParam(request, "current-user"); + if (QueryParamsValidator.hasQueryParameterValues(request, "current-user")) { + throw new InvalidArgumentException( + "It is prohibited to use the param current-user with values."); + } users.add(userService.getUser(this.currentUserContext.getUserid())); } diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java index d5e822192b..1cca53cd1e 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java @@ -148,16 +148,16 @@ private ObjectReferenceRepresentationModel getObjectReferenceResourceSample() { private AttachmentRepresentationModel getAttachmentResourceSample() { AttachmentRepresentationModel attachmentRepresentationModel = - new AttachmentRepresentationModel(); + new AttachmentRepresentationModel(); attachmentRepresentationModel.setAttachmentId("A11010"); attachmentRepresentationModel.setObjectReference(getObjectReferenceResourceSample()); ClassificationSummaryRepresentationModel classificationSummaryRepresentationModel = - new ClassificationSummaryRepresentationModel(); - classificationSummaryRepresentationModel - .setClassificationId("CLI:100000000000000000000000000000000004"); + new ClassificationSummaryRepresentationModel(); + classificationSummaryRepresentationModel.setClassificationId( + "CLI:100000000000000000000000000000000004"); classificationSummaryRepresentationModel.setKey("L11010"); - attachmentRepresentationModel - .setClassificationSummary(classificationSummaryRepresentationModel); + attachmentRepresentationModel.setClassificationSummary( + classificationSummaryRepresentationModel); return attachmentRepresentationModel; } @@ -1194,8 +1194,11 @@ void should_KeepFiltersInTheLinkOfTheResponse_When_GettingTasks() { @CsvSource({ "owner=user-1-1, 10", "owner-is-null, 65", + "owner-is-null=true, 65", "owner-is-null&owner=user-1-1, 75", + "owner-is-null=TRUE&owner=user-1-1, 75", "state=READY&owner-is-null&owner=user-1-1, 56", + "state=READY&owner-is-null=TrUe&owner=user-1-1, 56", }) void should_ReturnTasksWithVariousOwnerParameters_When_GettingTasks( String queryParams, int expectedSize) { @@ -1214,7 +1217,9 @@ Stream should_ThrowException_When_OwnerIsNullParamNotStrict() { List> list = List.of( Pair.of("When owner-is-null=", "?owner-is-null="), - Pair.of("When owner-is-null=anyValue", "?owner-is-null=anyValue1,anyValue2")); + Pair.of("When owner-is-null=owner-is-null", "?owner-is-null=owner-is-null"), + Pair.of( + "When owner-is-null=anyValue1,anyValue2", "?owner-is-null=anyValue1,anyValue2")); ThrowingConsumer> testOwnerIsNull = t -> { String url = restHelper.toUrl(RestEndpoints.URL_TASKS) + t.getRight(); @@ -1382,9 +1387,7 @@ void should_GetAllTasks_For_GettingSecondPageFilteredByPorAttributesSortedByType @Test void should_GetAllTasksWithComments_When_FilteringByHasCommentsIsSetToTrue() { - String url = - restHelper.toUrl(RestEndpoints.URL_TASKS) - + "?has-comments=true"; + String url = restHelper.toUrl(RestEndpoints.URL_TASKS) + "?has-comments=true"; HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ResponseEntity response = @@ -1393,7 +1396,8 @@ void should_GetAllTasksWithComments_When_FilteringByHasCommentsIsSetToTrue() { assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getContent()) .extracting(TaskSummaryRepresentationModel::getTaskId) - .containsExactlyInAnyOrder("TKI:000000000000000000000000000000000000", + .containsExactlyInAnyOrder( + "TKI:000000000000000000000000000000000000", "TKI:000000000000000000000000000000000001", "TKI:000000000000000000000000000000000002", "TKI:000000000000000000000000000000000004", @@ -1404,9 +1408,7 @@ void should_GetAllTasksWithComments_When_FilteringByHasCommentsIsSetToTrue() { @Test void should_GetAllTasksWithoutComments_When_FilteringByHasCommentsIsSetToFalse() { - String url = - restHelper.toUrl(RestEndpoints.URL_TASKS) - + "?has-comments=false"; + String url = restHelper.toUrl(RestEndpoints.URL_TASKS) + "?has-comments=false"; HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ResponseEntity response = @@ -1415,7 +1417,8 @@ void should_GetAllTasksWithoutComments_When_FilteringByHasCommentsIsSetToFalse() assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getContent()) .extracting(TaskSummaryRepresentationModel::getTaskId) - .doesNotContain("TKI:000000000000000000000000000000000000", + .doesNotContain( + "TKI:000000000000000000000000000000000000", "TKI:000000000000000000000000000000000001", "TKI:000000000000000000000000000000000002", "TKI:000000000000000000000000000000000004", @@ -1587,16 +1590,16 @@ void should_CreateTaskWithError_When_SpecifyingAttachmentWrong() { String url = restHelper.toUrl(RestEndpoints.URL_TASKS); HttpEntity auth = - new HttpEntity<>( - taskRepresentationModel, RestHelper.generateHeadersForUser("teamlead-1")); + new HttpEntity<>( + taskRepresentationModel, RestHelper.generateHeadersForUser("teamlead-1")); ThrowingCallable httpCall = - () -> TEMPLATE.exchange(url, HttpMethod.POST, auth, TASK_MODEL_TYPE); + () -> TEMPLATE.exchange(url, HttpMethod.POST, auth, TASK_MODEL_TYPE); assertThatThrownBy(httpCall) - .extracting(HttpStatusCodeException.class::cast) - .extracting(HttpStatusCodeException::getStatusCode) - .isEqualTo(HttpStatus.BAD_REQUEST); + .extracting(HttpStatusCodeException.class::cast) + .extracting(HttpStatusCodeException::getStatusCode) + .isEqualTo(HttpStatus.BAD_REQUEST); } @Test @@ -1826,13 +1829,12 @@ void should_ChangeValueOfModified_When_UpdatingTask() { @Test void should_ThrowError_When_UpdatingTaskWithBadAttachment() { String url = - restHelper.toUrl(RestEndpoints.URL_TASKS_ID, - "TKI:100000000000000000000000000000000000"); + restHelper.toUrl(RestEndpoints.URL_TASKS_ID, "TKI:100000000000000000000000000000000000"); HttpEntity httpEntityWithoutBody = - new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); + new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ResponseEntity responseGet = - TEMPLATE.exchange(url, HttpMethod.GET, httpEntityWithoutBody, TASK_MODEL_TYPE); + TEMPLATE.exchange(url, HttpMethod.GET, httpEntityWithoutBody, TASK_MODEL_TYPE); final TaskRepresentationModel originalTask = responseGet.getBody(); @@ -1840,17 +1842,16 @@ void should_ThrowError_When_UpdatingTaskWithBadAttachment() { attachmentRepresentationModel.setTaskId(originalTask.getTaskId() + "wrongId"); originalTask.setAttachments(Lists.newArrayList(attachmentRepresentationModel)); - HttpEntity httpEntity = - new HttpEntity<>(originalTask, RestHelper.generateHeadersForUser("teamlead-1")); + new HttpEntity<>(originalTask, RestHelper.generateHeadersForUser("teamlead-1")); ThrowingCallable httpCall = - () -> TEMPLATE.exchange(url, HttpMethod.PUT, httpEntity, TASK_MODEL_TYPE); + () -> TEMPLATE.exchange(url, HttpMethod.PUT, httpEntity, TASK_MODEL_TYPE); assertThatThrownBy(httpCall) - .extracting(HttpStatusCodeException.class::cast) - .extracting(HttpStatusCodeException::getStatusCode) - .isEqualTo(HttpStatus.BAD_REQUEST); + .extracting(HttpStatusCodeException.class::cast) + .extracting(HttpStatusCodeException::getStatusCode) + .isEqualTo(HttpStatus.BAD_REQUEST); } } @@ -2048,8 +2049,7 @@ void should_SetTransferFlagToTrueAndOwnerToNull_When_TransferringWithoutRequestB } @TestFactory - Stream - should_ReturnFailedTasks_When_TransferringTasks() { + Stream should_ReturnFailedTasks_When_TransferringTasks() { Iterator> iterator = Arrays.asList(Pair.of(true, "user-1-1"), Pair.of(false, "user-1-2")).iterator(); diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/user/rest/UserControllerIntTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/user/rest/UserControllerIntTest.java index e32e95076d..baedda8ba2 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/user/rest/UserControllerIntTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/user/rest/UserControllerIntTest.java @@ -31,7 +31,7 @@ class UserControllerIntTest { } @Test - void should_ReturnExistingUser() throws Exception { + void should_ReturnExistingUser() { String url = restHelper.toUrl(RestEndpoints.URL_USERS_ID, "TEAMLEAD-1"); HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); @@ -45,7 +45,7 @@ void should_ReturnExistingUser() throws Exception { } @Test - void should_ReturnExistingUsers() throws Exception { + void should_ReturnExistingUsers() { String url = restHelper.toUrl(RestEndpoints.URL_USERS) + "?user-id=user-1-1&user-id=USER-1-2"; HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); @@ -69,11 +69,11 @@ void should_ReturnCurrentUser() { HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ResponseEntity response = - TEMPLATE.exchange( - url, - HttpMethod.GET, - auth, - ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); + TEMPLATE.exchange( + url, + HttpMethod.GET, + auth, + ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getContent()).hasSize(1); assertThat(response.getBody().getContent()).extracting("userId").containsExactly("teamlead-1"); @@ -85,17 +85,17 @@ void should_ReturnExceptionCurrentUserWithBadValue() { HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ThrowingCallable httpCall = - () -> - TEMPLATE.exchange( - url, - HttpMethod.GET, - auth, - ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); + () -> + TEMPLATE.exchange( + url, + HttpMethod.GET, + auth, + ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); assertThatThrownBy(httpCall) - .isInstanceOf(HttpStatusCodeException.class) - .extracting(HttpStatusCodeException.class::cast) - .extracting(HttpStatusCodeException::getStatusCode) - .isEqualTo(HttpStatus.BAD_REQUEST); + .isInstanceOf(HttpStatusCodeException.class) + .extracting(HttpStatusCodeException.class::cast) + .extracting(HttpStatusCodeException::getStatusCode) + .isEqualTo(HttpStatus.BAD_REQUEST); } @Test @@ -104,17 +104,17 @@ void should_ReturnExceptionCurrentUserWithEmptyValue() { HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ThrowingCallable httpCall = - () -> - TEMPLATE.exchange( - url, - HttpMethod.GET, - auth, - ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); + () -> + TEMPLATE.exchange( + url, + HttpMethod.GET, + auth, + ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); assertThatThrownBy(httpCall) - .isInstanceOf(HttpStatusCodeException.class) - .extracting(HttpStatusCodeException.class::cast) - .extracting(HttpStatusCodeException::getStatusCode) - .isEqualTo(HttpStatus.BAD_REQUEST); + .isInstanceOf(HttpStatusCodeException.class) + .extracting(HttpStatusCodeException.class::cast) + .extracting(HttpStatusCodeException::getStatusCode) + .isEqualTo(HttpStatus.BAD_REQUEST); } @Test @@ -123,38 +123,39 @@ void should_ReturnOnlyCurrentUserWhileUsingUserIds() { HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ResponseEntity response = - TEMPLATE.exchange( - url, - HttpMethod.GET, - auth, - ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); + TEMPLATE.exchange( + url, + HttpMethod.GET, + auth, + ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getContent()).hasSize(1); assertThat(response.getBody().getContent()).extracting("userId").containsExactly("teamlead-1"); } @Test - void should_ReturnExistingUsersAndCurrentUser() throws Exception { - String url = restHelper.toUrl(RestEndpoints.URL_USERS) + void should_ReturnExistingUsersAndCurrentUser() { + String url = + restHelper.toUrl(RestEndpoints.URL_USERS) + "?user-id=user-1-1&user-id=USER-1-2¤t-user"; HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ResponseEntity responseEntity = - TEMPLATE.exchange( - url, - HttpMethod.GET, - auth, - ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); + TEMPLATE.exchange( + url, + HttpMethod.GET, + auth, + ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); UserCollectionRepresentationModel response = responseEntity.getBody(); assertThat(response).isNotNull(); assertThat(response.getContent()).hasSize(3); assertThat(response.getContent()) - .extracting("userId") - .containsExactlyInAnyOrder("user-1-1", "user-1-2", "teamlead-1"); + .extracting("userId") + .containsExactlyInAnyOrder("user-1-1", "user-1-2", "teamlead-1"); } @Test - void should_ReturnExistingUsers_When_ParameterContainsDuplicateAndInvalidIds() throws Exception { + void should_ReturnExistingUsers_When_ParameterContainsDuplicateAndInvalidIds() { // also testing different query parameter format String url = restHelper.toUrl(RestEndpoints.URL_USERS) @@ -182,8 +183,7 @@ void should_ReturnExistingUsers_When_ParameterContainsDuplicateAndInvalidIds() t } @Test - void should_CreateValidUser_When_CallingCreateEndpointWithAllAttributesExceptDomains() - throws Exception { + void should_CreateValidUser_When_CallingCreateEndpoint() { UserRepresentationModel newUser = new UserRepresentationModel(); newUser.setUserId("12345"); newUser.setGroups(Set.of("group1", "group2")); @@ -262,7 +262,7 @@ void should_CreateValidUser_When_CallingCreateEndpointWithoutGroupsPermissionsDo } @Test - void should_UpdateExistingUser_When_CallingUpdateEndpoint() throws Exception { + void should_UpdateExistingUser_When_CallingUpdateEndpoint() { String url = restHelper.toUrl(RestEndpoints.URL_USERS_ID, "teamlead-1"); HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));