From 235bba959551a27b7be1f28907a8b18c406e625e Mon Sep 17 00:00:00 2001 From: Roman_Barannyk Date: Tue, 19 Sep 2023 16:48:57 +0300 Subject: [PATCH] CIRC-1880 update requests error messages --- .../domain/CreateRequestService.java | 8 ++-- .../domain/RequestServiceUtility.java | 5 ++- .../ProxyRelationshipValidator.java | 5 ++- .../validation/RequestLoanValidator.java | 12 ++++-- .../ServicePointPickupLocationValidator.java | 5 ++- .../RequestFromRepresentationService.java | 16 ++++--- .../folio/circulation/support/ErrorCode.java | 12 +++++- ...equestScheduledNoticesProcessingTests.java | 9 +++- .../requests/RequestsAPICreationTests.java | 42 +++++++++++++------ .../scenarios/CancelRequestTests.java | 8 +++- .../requests/scenarios/MoveRequestTests.java | 6 ++- 11 files changed, 89 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/folio/circulation/domain/CreateRequestService.java b/src/main/java/org/folio/circulation/domain/CreateRequestService.java index 2c491f3e28..34b7aacaba 100644 --- a/src/main/java/org/folio/circulation/domain/CreateRequestService.java +++ b/src/main/java/org/folio/circulation/domain/CreateRequestService.java @@ -23,6 +23,7 @@ import static org.folio.circulation.resources.handlers.error.CirculationErrorType.REQUEST_NOT_ALLOWED_FOR_PATRON_TITLE_COMBINATION; import static org.folio.circulation.resources.handlers.error.CirculationErrorType.TLR_RECALL_WITHOUT_OPEN_LOAN_OR_RECALLABLE_ITEM; import static org.folio.circulation.resources.handlers.error.CirculationErrorType.USER_IS_INACTIVE; +import static org.folio.circulation.support.ErrorCode.PAGEABLE_AVAILABLE_ITEM_FOUND; import static org.folio.circulation.support.ValidationErrorFailure.failedValidation; import static org.folio.circulation.support.results.MappingFunctions.when; import static org.folio.circulation.support.results.Result.of; @@ -145,12 +146,11 @@ private Result failValidationWhenPageableItemsExist( private Result failedValidationHoldAndRecallNotAllowed(Request request, String availableItemId) { - String errorMessage = "Hold/Recall TLR not allowed: pageable available item found for instance"; - + String errorMessage = "Hold/Recall title level request not allowed: pageable available item found for instance"; log.info("{}. Pageable item(s): {}", errorMessage, availableItemId); - return failedValidation(errorMessage, - Map.of(ITEM_ID, availableItemId, INSTANCE_ID, request.getInstanceId())); + return failedValidation(errorMessage, Map.of(ITEM_ID, availableItemId, INSTANCE_ID, + request.getInstanceId()), PAGEABLE_AVAILABLE_ITEM_FOUND); } private CompletableFuture> checkInstance( diff --git a/src/main/java/org/folio/circulation/domain/RequestServiceUtility.java b/src/main/java/org/folio/circulation/domain/RequestServiceUtility.java index c2d8ee0200..50a966170d 100644 --- a/src/main/java/org/folio/circulation/domain/RequestServiceUtility.java +++ b/src/main/java/org/folio/circulation/domain/RequestServiceUtility.java @@ -3,6 +3,7 @@ import static java.lang.String.format; import static org.folio.circulation.domain.representations.RequestProperties.PICKUP_SERVICE_POINT_ID; import static org.folio.circulation.domain.representations.RequestProperties.REQUEST_TYPE; +import static org.folio.circulation.support.ErrorCode.ALREADY_REQUESTED; import static org.folio.circulation.support.ValidationErrorFailure.failedValidation; import static org.folio.circulation.support.results.Result.of; import static org.folio.circulation.support.results.Result.succeeded; @@ -218,7 +219,7 @@ private static Result alreadyRequestedFailure( parameters.put(INSTANCE_ID, requestBeingPlaced.getInstanceId()); message = requestBeingPlaced.getOperation() == Operation.MOVE - ? "Not allowed to move TLR to the same item" + ? "Not allowed to move title level page request to the same item" : "This requester already has an open request for this instance"; } else { parameters.put(REQUESTER_ID, requestBeingPlaced.getUserId()); @@ -234,7 +235,7 @@ private static Result alreadyRequestedFailure( message = "This requester already has an open request for this item"; } - return failedValidation(message, parameters); + return failedValidation(message, parameters, ALREADY_REQUESTED); } static boolean isTheSameRequester(RequestAndRelatedRecords it, Request that) { diff --git a/src/main/java/org/folio/circulation/domain/validation/ProxyRelationshipValidator.java b/src/main/java/org/folio/circulation/domain/validation/ProxyRelationshipValidator.java index e4e5c90a97..93ae7d02c8 100644 --- a/src/main/java/org/folio/circulation/domain/validation/ProxyRelationshipValidator.java +++ b/src/main/java/org/folio/circulation/domain/validation/ProxyRelationshipValidator.java @@ -1,6 +1,7 @@ package org.folio.circulation.domain.validation; import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.folio.circulation.support.ErrorCode.USER_CANNOT_BE_PROXY_FOR_THEMSELVES; import static org.folio.circulation.support.ValidationErrorFailure.singleValidationError; import static org.folio.circulation.support.http.client.CqlQuery.exactMatch; import static org.folio.circulation.support.results.Result.failed; @@ -51,8 +52,8 @@ public CompletableFuture> refuseWhenInva if (StringUtils.equals(userRelatedRecord.getProxyUserId(), userRelatedRecord.getUserId())) { log.info("refuseWhenInvalid:: proxy user ID is equal to user ID"); return completedFuture(failed(singleValidationError( - "User cannot be proxy for themself", "proxyUserId", - userRelatedRecord.getProxyUserId()))); + "User cannot be proxy for themselves", "proxyUserId", + userRelatedRecord.getProxyUserId(), USER_CANNOT_BE_PROXY_FOR_THEMSELVES))); } return succeeded(userRelatedRecord).failAfter( diff --git a/src/main/java/org/folio/circulation/domain/validation/RequestLoanValidator.java b/src/main/java/org/folio/circulation/domain/validation/RequestLoanValidator.java index 63cbaf41d4..ce13d6552b 100644 --- a/src/main/java/org/folio/circulation/domain/validation/RequestLoanValidator.java +++ b/src/main/java/org/folio/circulation/domain/validation/RequestLoanValidator.java @@ -1,5 +1,7 @@ package org.folio.circulation.domain.validation; +import static org.folio.circulation.support.ErrorCode.REQUESTER_ALREADY_HAS_LOAN_FOR_INSTANCES_ITEM; +import static org.folio.circulation.support.ErrorCode.REQUESTER_ALREADY_HAS_THIS_ITEM_ON_LOAN; import static org.folio.circulation.support.ValidationErrorFailure.failedValidation; import static org.folio.circulation.support.ValidationErrorFailure.singleValidationError; import static org.folio.circulation.support.http.client.PageLimit.limit; @@ -26,6 +28,7 @@ import org.folio.circulation.domain.RequestAndRelatedRecords; import org.folio.circulation.infrastructure.storage.loans.LoanRepository; import org.folio.circulation.storage.ItemByInstanceIdFinder; +import org.folio.circulation.support.ErrorCode; import org.folio.circulation.support.http.client.PageLimit; import org.folio.circulation.support.http.server.ValidationError; import org.folio.circulation.support.results.Result; @@ -57,9 +60,10 @@ public CompletableFuture> refuseWhenUserHasAlre parameters.put("userId", request.getUserId()); parameters.put("loanId", loan.getId()); - String message = "This requester currently has this item on loan."; + String message = "This requester already has this item on loan"; - return singleValidationError(new ValidationError(message, parameters)); + return singleValidationError(new ValidationError(message, parameters, + REQUESTER_ALREADY_HAS_THIS_ITEM_ON_LOAN)); }).map(loan -> requestAndRelatedRecords)); } @@ -112,7 +116,7 @@ private Result oneOfTheItemsIsAlreadyLoanedFailure( parameters.put("userId", requestAndRelatedRecords.getRequest().getUserId()); parameters.put("itemId", loan.getItemId()); - return failedValidation("One of the items of the requested title is already loaned to " + - "the requester", parameters); + return failedValidation("This requester already has a loan for one of the instance's items", + parameters, REQUESTER_ALREADY_HAS_LOAN_FOR_INSTANCES_ITEM); } } diff --git a/src/main/java/org/folio/circulation/domain/validation/ServicePointPickupLocationValidator.java b/src/main/java/org/folio/circulation/domain/validation/ServicePointPickupLocationValidator.java index c726e6e186..dcd5dc0a45 100644 --- a/src/main/java/org/folio/circulation/domain/validation/ServicePointPickupLocationValidator.java +++ b/src/main/java/org/folio/circulation/domain/validation/ServicePointPickupLocationValidator.java @@ -1,5 +1,6 @@ package org.folio.circulation.domain.validation; +import static org.folio.circulation.support.ErrorCode.HOLD_SHELF_REQUESTS_REQUIRE_PICKUP_SERVICE_POINT; import static org.folio.circulation.support.ErrorCode.SERVICE_POINT_IS_NOT_PICKUP_LOCATION; import static org.folio.circulation.support.ValidationErrorFailure.failedValidation; import static org.folio.circulation.support.results.Result.succeeded; @@ -42,8 +43,8 @@ public Result refuseInvalidPickupServicePoint( log.info("refuseInvalidPickupServicePoint:: Hold Shelf Fulfillment Requests require a " + "Pickup Service Point"); return failedValidation( - "Hold Shelf Fulfillment Requests require a Pickup Service Point", - "id", request.getId()); + "Hold shelf fulfillment requests require a Pickup service point", + "id", request.getId(), HOLD_SHELF_REQUESTS_REQUIRE_PICKUP_SERVICE_POINT); } else { log.info("refuseInvalidPickupServicePoint:: No pickup service point specified for request"); return succeeded(requestAndRelatedRecords); diff --git a/src/main/java/org/folio/circulation/resources/RequestFromRepresentationService.java b/src/main/java/org/folio/circulation/resources/RequestFromRepresentationService.java index f9bf97ae06..a57d82e972 100644 --- a/src/main/java/org/folio/circulation/resources/RequestFromRepresentationService.java +++ b/src/main/java/org/folio/circulation/resources/RequestFromRepresentationService.java @@ -23,6 +23,9 @@ import static org.folio.circulation.resources.handlers.error.CirculationErrorType.INVALID_PROXY_RELATIONSHIP; import static org.folio.circulation.resources.handlers.error.CirculationErrorType.NO_AVAILABLE_ITEMS_FOR_TLR; import static org.folio.circulation.resources.handlers.error.CirculationErrorType.TLR_RECALL_WITHOUT_OPEN_LOAN_OR_RECALLABLE_ITEM; +import static org.folio.circulation.support.ErrorCode.FULFILLMENT_PREFERENCE_IS_NOT_ALLOWED; +import static org.folio.circulation.support.ErrorCode.INSTANCE_HAS_NO_ITEM_ID; +import static org.folio.circulation.support.ErrorCode.REQUEST_LEVEL_IS_NOT_ALLOWED; import static org.folio.circulation.support.ValidationErrorFailure.failedValidation; import static org.folio.circulation.support.http.client.PageLimit.limit; import static org.folio.circulation.support.json.JsonPropertyFetcher.getDateTimeProperty; @@ -74,6 +77,7 @@ import org.folio.circulation.services.ItemForTlrService; import org.folio.circulation.storage.ItemByInstanceIdFinder; import org.folio.circulation.support.BadRequestFailure; +import org.folio.circulation.support.ErrorCode; import org.folio.circulation.support.http.client.PageLimit; import org.folio.circulation.support.request.RequestRelatedRepositories; import org.folio.circulation.support.results.Result; @@ -445,8 +449,8 @@ private Result validateRequestLevel(Request request) { .collect(Collectors.joining(", ")); return failedValidation( - "requestLevel must be one of the following: " + allowedStatusesJoined, "requestLevel", - requestLevelRaw); + "Request level must be one of the following: " + allowedStatusesJoined, "requestLevel", + requestLevelRaw, REQUEST_LEVEL_IS_NOT_ALLOWED); } return succeeded(request); @@ -457,9 +461,9 @@ private Result validatefulfillmentPreference(Request request) { .filter(value -> value.equals(request.getfulfillmentPreferenceName())) .findFirst() .map(value -> succeeded(request)) - .orElseGet(() -> failedValidation("fulfillmentPreference must be one of the following: " + + .orElseGet(() -> failedValidation("Fulfillment preference must be one of the following: " + join(", ", RequestFulfillmentPreference.allowedValues()), "fulfillmentPreference", - request.getfulfillmentPreferenceName())); + request.getfulfillmentPreferenceName(), FULFILLMENT_PREFERENCE_IS_NOT_ALLOWED)); } private Result refuseWhenNoInstanceId(Result result) { @@ -535,8 +539,8 @@ private Result validateAbsenceOfItemLinkInTlr(Request request) { Map errorParameters = new HashMap<>(); errorParameters.put("itemId", itemId); errorParameters.put("holdingsRecordId", holdingsRecordId); - return failedValidation("Attempt to create TLR request linked to an item", - errorParameters); + return failedValidation("Cannot create a title level page request " + + "for this instance ID with no item ID", errorParameters, INSTANCE_HAS_NO_ITEM_ID); } else { return of(() -> request); diff --git a/src/main/java/org/folio/circulation/support/ErrorCode.java b/src/main/java/org/folio/circulation/support/ErrorCode.java index f4720f2fc7..f295c177a1 100644 --- a/src/main/java/org/folio/circulation/support/ErrorCode.java +++ b/src/main/java/org/folio/circulation/support/ErrorCode.java @@ -13,5 +13,15 @@ public enum ErrorCode { REQUEST_ALREADY_CLOSED, REQUEST_NOT_ALLOWED_FOR_PATRON_TITLE_COMBINATION, REQUEST_PICKUP_SERVICE_POINT_IS_NOT_ALLOWED, - SERVICE_POINT_IS_NOT_PICKUP_LOCATION + SERVICE_POINT_IS_NOT_PICKUP_LOCATION, + REQUEST_LEVEL_IS_NOT_ALLOWED, + FULFILLMENT_PREFERENCE_IS_NOT_ALLOWED, + REQUESTER_ALREADY_HAS_LOAN_FOR_INSTANCES_ITEM, + REQUESTER_ALREADY_HAS_THIS_ITEM_ON_LOAN, + INSTANCE_HAS_NO_ITEM_ID, + PAGEABLE_AVAILABLE_ITEM_FOUND, + USER_CANNOT_BE_PROXY_FOR_THEMSELVES, + MOVING_REQUEST_TO_THE_SAME_ITEM, + ALREADY_REQUESTED, + HOLD_SHELF_REQUESTS_REQUIRE_PICKUP_SERVICE_POINT } diff --git a/src/test/java/api/requests/RequestScheduledNoticesProcessingTests.java b/src/test/java/api/requests/RequestScheduledNoticesProcessingTests.java index 26b2afd16d..1d29fd17fc 100644 --- a/src/test/java/api/requests/RequestScheduledNoticesProcessingTests.java +++ b/src/test/java/api/requests/RequestScheduledNoticesProcessingTests.java @@ -11,6 +11,7 @@ import static api.support.matchers.PatronNoticeMatcher.hasEmailNoticeProperties; import static api.support.matchers.RequestMatchers.isOpenAwaitingPickup; import static api.support.matchers.TextDateTimeMatcher.isEquivalentTo; +import static api.support.matchers.ValidationErrorMatchers.hasCode; import static api.support.matchers.ValidationErrorMatchers.hasErrorWith; import static api.support.matchers.ValidationErrorMatchers.hasMessage; import static api.support.utl.PatronNoticeTestHelper.verifyNumberOfPublishedEvents; @@ -25,6 +26,7 @@ import static org.folio.circulation.domain.notice.NoticeEventType.REQUEST_EXPIRATION; import static org.folio.circulation.domain.representations.logs.LogEventType.NOTICE; import static org.folio.circulation.domain.representations.logs.LogEventType.NOTICE_ERROR; +import static org.folio.circulation.support.ErrorCode.REQUEST_LEVEL_IS_NOT_ALLOWED; import static org.folio.circulation.support.json.JsonPropertyFetcher.getDateTimeProperty; import static org.folio.circulation.support.utils.ClockUtil.getLocalDate; import static org.folio.circulation.support.utils.ClockUtil.getZonedDateTime; @@ -33,6 +35,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.nullValue; @@ -45,6 +48,7 @@ import java.util.stream.Stream; import org.folio.circulation.domain.policy.Period; +import org.folio.circulation.support.ErrorCode; import org.folio.circulation.support.http.client.Response; import org.hamcrest.Matcher; import org.junit.FixMethodOrder; @@ -634,8 +638,9 @@ void titleLevelRequestExpirationNoticeShouldNotBeCreatedWithDisabledTlr(UUID exp Response response = requestsFixture.attemptPlace(buildTitleLevelRequest(requestExpiration)); assertThat(response.getStatusCode(), is(422)); - assertThat(response.getJson(), hasErrorWith( - hasMessage("requestLevel must be one of the following: \"Item\""))); + assertThat(response.getJson(), hasErrorWith(allOf( + hasMessage("Request level must be one of the following: \"Item\""), + hasCode(REQUEST_LEVEL_IS_NOT_ALLOWED)))); verifyNumberOfScheduledNotices(0); } diff --git a/src/test/java/api/requests/RequestsAPICreationTests.java b/src/test/java/api/requests/RequestsAPICreationTests.java index a2294c68ca..1191689af4 100644 --- a/src/test/java/api/requests/RequestsAPICreationTests.java +++ b/src/test/java/api/requests/RequestsAPICreationTests.java @@ -60,6 +60,11 @@ import static org.folio.circulation.domain.representations.logs.LogEventType.NOTICE; import static org.folio.circulation.domain.representations.logs.LogEventType.NOTICE_ERROR; import static org.folio.circulation.domain.representations.logs.LogEventType.REQUEST_CREATED_THROUGH_OVERRIDE; +import static org.folio.circulation.support.ErrorCode.FULFILLMENT_PREFERENCE_IS_NOT_ALLOWED; +import static org.folio.circulation.support.ErrorCode.HOLD_SHELF_REQUESTS_REQUIRE_PICKUP_SERVICE_POINT; +import static org.folio.circulation.support.ErrorCode.REQUESTER_ALREADY_HAS_LOAN_FOR_INSTANCES_ITEM; +import static org.folio.circulation.support.ErrorCode.REQUESTER_ALREADY_HAS_THIS_ITEM_ON_LOAN; +import static org.folio.circulation.support.ErrorCode.REQUEST_LEVEL_IS_NOT_ALLOWED; import static org.folio.circulation.support.utils.ClockUtil.getZonedDateTime; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.containsString; @@ -541,7 +546,8 @@ void cannotCreateTitleLevelRequestWhenTlrDisabled(String requestType) { assertThat(postResponse, hasStatus(HTTP_UNPROCESSABLE_ENTITY)); assertThat(postResponse.getJson(), hasErrorWith(allOf( - hasMessage("requestLevel must be one of the following: \"Item\""), + hasMessage("Request level must be one of the following: \"Item\""), + hasCode(REQUEST_LEVEL_IS_NOT_ALLOWED), hasParameter("requestLevel", "Title")))); } @@ -580,7 +586,8 @@ void cannotCreateRequestWithNonExistentRequestLevel() { assertThat(postResponse, hasStatus(HTTP_UNPROCESSABLE_ENTITY)); assertThat(postResponse.getJson(), hasErrorWith(allOf( - hasMessage("requestLevel must be one of the following: \"Item\""), + hasMessage("Request level must be one of the following: \"Item\""), + hasCode(REQUEST_LEVEL_IS_NOT_ALLOWED), hasParameter("requestLevel", "invalid")))); } @@ -631,7 +638,8 @@ void cannotCreateRequestWithNonExistentRequestLevelWhenTlrEnabled() { assertThat(postResponse, hasStatus(HTTP_UNPROCESSABLE_ENTITY)); assertThat(postResponse.getJson(), hasErrorWith(allOf( - hasMessage("requestLevel must be one of the following: \"Item\", \"Title\""), + hasMessage("Request level must be one of the following: \"Item\", \"Title\""), + hasCode(REQUEST_LEVEL_IS_NOT_ALLOWED), hasParameter("requestLevel", "invalid")))); } @@ -663,7 +671,8 @@ void cannotCreateTlrRequestWhenUserHasLoanForSomeItemsOfInstance() { assertThat(postResponse, hasStatus(HTTP_UNPROCESSABLE_ENTITY)); assertThat(postResponse.getJson(), hasErrorWith(allOf( - hasMessage("One of the items of the requested title is already loaned to the requester"), + hasMessage("This requester already has a loan for one of the instance's items"), + hasCode(REQUESTER_ALREADY_HAS_LOAN_FOR_INSTANCES_ITEM), hasParameter("itemId", item.getId().toString()), hasParameter("userId", usersFixture.jessica().getId().toString())))); } @@ -796,6 +805,7 @@ void cannotCreateRequestItemAlreadyCheckedOutToRequester() { assertThat(postResponse.getJson(), hasErrors(1)); assertThat(postResponse.getJson(), hasErrorWith(allOf( hasMessage("This requester currently has this item on loan."), + hasCode(REQUESTER_ALREADY_HAS_THIS_ITEM_ON_LOAN), hasUUIDParameter("itemId", smallAngryPlanet.getId()), hasUUIDParameter("userId", rebecca.getId())))); } @@ -1263,8 +1273,9 @@ void cannotCreateARequestWithoutAPickupLocationServicePoint() { assertThat(postResponse, hasStatus(HTTP_UNPROCESSABLE_ENTITY)); assertThat(postResponse.getJson(), hasErrors(1)); - assertThat(postResponse.getJson(), hasErrorWith( - hasMessage("Hold Shelf Fulfillment Requests require a Pickup Service Point"))); + assertThat(postResponse.getJson(), hasErrorWith(allOf( + hasMessage("Hold Shelf Fulfillment Requests require a Pickup service point"), + hasCode(HOLD_SHELF_REQUESTS_REQUIRE_PICKUP_SERVICE_POINT)))); } @Test @@ -2969,8 +2980,9 @@ void shouldNotCreateRequestWhenInstanceItemRequesterAndPickupServicePointAreNotP hasMessage("A valid user and patron group are required. User is null"), hasNullParameter("userId")))); - assertThat(responseJson, hasErrorWith( - hasMessage("Hold Shelf Fulfillment Requests require a Pickup Service Point"))); + assertThat(responseJson, hasErrorWith(allOf( + hasMessage("Hold Shelf Fulfillment Requests require a Pickup service point"), + hasCode(HOLD_SHELF_REQUESTS_REQUIRE_PICKUP_SERVICE_POINT)))); } @Test @@ -3163,8 +3175,9 @@ void titleLevelRequestConfirmationNoticeShouldNotBeSentWithDisabledTlr( Response response = requestsFixture.attemptPlace(buildTitleLevelRequest()); assertThat(response.getStatusCode(), CoreMatchers.is(422)); - assertThat(response.getJson(), hasErrorWith( - hasMessage("requestLevel must be one of the following: \"Item\""))); + assertThat(response.getJson(), hasErrorWith(allOf( + hasMessage("Request level must be one of the following: \"Item\""), + hasCode(REQUEST_LEVEL_IS_NOT_ALLOWED)))); verifyNumberOfSentNotices(0); verifyNumberOfPublishedEvents(NOTICE, 0); verifyNumberOfPublishedEvents(NOTICE_ERROR, 0); @@ -3531,7 +3544,8 @@ void pageRequestShouldNotBeCreatedIffulfillmentPreferenceIsNotValid(String fulfi assertThat(response, hasStatus(HTTP_UNPROCESSABLE_ENTITY)); assertThat(response.getJson(), hasErrorWith(allOf( - hasMessage("fulfillmentPreference must be one of the following: Hold Shelf, Delivery"), + hasMessage("Fulfillment preference must be one of the following: Hold Shelf, Delivery"), + hasCode(FULFILLMENT_PREFERENCE_IS_NOT_ALLOWED), hasParameter("fulfillmentPreference", fulfillmentPreference)))); var itemById = itemsFixture.getById(item.getId()); assertThat(itemById.getResponse().getJson().getJsonObject("status").getString("name"), @@ -4399,7 +4413,8 @@ void shouldNotFillInMissingRequestPropertiesWhenHoldingsRecordIdIsPresent() { assertThat(response, hasStatus(HTTP_UNPROCESSABLE_ENTITY)); assertThat(response.getJson(), hasErrorWith(allOf( - hasMessage("requestLevel must be one of the following: \"Item\""), + hasMessage("Request level must be one of the following: \"Item\""), + hasCode(REQUEST_LEVEL_IS_NOT_ALLOWED), hasNullParameter("requestLevel")))); } @@ -4421,7 +4436,8 @@ void shouldNotFillInMissingRequestPropertiesWhenInstanceIdIsPresent() { assertThat(response, hasStatus(HTTP_UNPROCESSABLE_ENTITY)); assertThat(response.getJson(), hasErrors(1)); assertThat(response.getJson(), hasErrorWith(allOf( - hasMessage("requestLevel must be one of the following: \"Item\""), + hasMessage("Request level must be one of the following: \"Item\""), + hasCode(REQUEST_LEVEL_IS_NOT_ALLOWED), hasNullParameter("requestLevel")))); } diff --git a/src/test/java/api/requests/scenarios/CancelRequestTests.java b/src/test/java/api/requests/scenarios/CancelRequestTests.java index 24bb294144..0b2115a02c 100644 --- a/src/test/java/api/requests/scenarios/CancelRequestTests.java +++ b/src/test/java/api/requests/scenarios/CancelRequestTests.java @@ -3,6 +3,7 @@ import static api.support.PubsubPublisherTestUtils.assertThatPublishedNoticeLogRecordEventsAreValid; import static api.support.builders.RequestBuilder.OPEN_NOT_YET_FILLED; import static api.support.matchers.ItemStatusCodeMatcher.hasItemStatus; +import static api.support.matchers.ValidationErrorMatchers.hasCode; import static api.support.matchers.ValidationErrorMatchers.hasErrorWith; import static api.support.matchers.ValidationErrorMatchers.hasMessage; import static api.support.utl.PatronNoticeTestHelper.verifyNumberOfPublishedEvents; @@ -15,6 +16,7 @@ import static org.folio.circulation.support.utils.ClockUtil.getZonedDateTime; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.contains; import java.time.LocalDate; @@ -24,6 +26,7 @@ import java.util.UUID; import org.folio.circulation.domain.MultipleRecords; +import org.folio.circulation.support.ErrorCode; import org.folio.circulation.support.http.client.Response; import org.folio.circulation.support.utils.ClockUtil; import org.hamcrest.CoreMatchers; @@ -333,8 +336,9 @@ void titleLevelRequestCancellationNoticeShouldNotBeSentWithDisabledTlr( Response response = requestsFixture.attemptCancelRequest(request); assertThat(response.getStatusCode(), CoreMatchers.is(422)); - assertThat(response.getJson(), hasErrorWith( - hasMessage("requestLevel must be one of the following: \"Item\""))); + assertThat(response.getJson(), hasErrorWith(allOf( + hasMessage("Request level must be one of the following: \"Item\""), + hasCode(ErrorCode.REQUEST_LEVEL_IS_NOT_ALLOWED)))); verifyNumberOfSentNotices(0); } diff --git a/src/test/java/api/requests/scenarios/MoveRequestTests.java b/src/test/java/api/requests/scenarios/MoveRequestTests.java index 2a9abed9e4..ce8801e2b9 100644 --- a/src/test/java/api/requests/scenarios/MoveRequestTests.java +++ b/src/test/java/api/requests/scenarios/MoveRequestTests.java @@ -7,6 +7,7 @@ import static api.support.matchers.EventMatchers.isValidLoanDueDateChangedEvent; import static api.support.matchers.ItemStatusCodeMatcher.hasItemStatus; import static api.support.matchers.TextDateTimeMatcher.isEquivalentTo; +import static api.support.matchers.ValidationErrorMatchers.hasCode; import static api.support.matchers.ValidationErrorMatchers.hasErrorWith; import static api.support.matchers.ValidationErrorMatchers.hasMessage; import static api.support.matchers.ValidationErrorMatchers.hasParameter; @@ -20,6 +21,7 @@ import static org.folio.circulation.domain.representations.ItemProperties.CALL_NUMBER_COMPONENTS; import static org.folio.circulation.domain.representations.RequestProperties.REQUEST_TYPE; import static org.folio.circulation.domain.representations.logs.LogEventType.REQUEST_MOVED; +import static org.folio.circulation.support.ErrorCode.ALREADY_REQUESTED; import static org.folio.circulation.support.utils.ClockUtil.getClock; import static org.folio.circulation.support.utils.ClockUtil.getZonedDateTime; import static org.folio.circulation.support.utils.ClockUtil.setClock; @@ -47,6 +49,7 @@ import org.folio.circulation.domain.RequestStatus; import org.folio.circulation.domain.RequestType; import org.folio.circulation.domain.policy.Period; +import org.folio.circulation.support.ErrorCode; import org.folio.circulation.support.http.client.Response; import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; @@ -425,7 +428,8 @@ void cannotMoveTlrToTheSameItem() { Response response = requestsFixture.attemptMove(new MoveRequestBuilder(nodPage.getId(), item.getId())); assertThat(response.getJson(), hasErrorWith(allOf( - hasMessage("Not allowed to move TLR to the same item"), + hasMessage("Not allowed to move title level page request to the same item"), + hasCode(ALREADY_REQUESTED), hasParameter("requesterId", jessica.getId().toString()), hasParameter("instanceId", item.getInstanceId().toString())))); }