Skip to content

Commit

Permalink
[MODORDSTOR-381] Fix failing unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Saba-Zedginidze-EPAM committed Apr 5, 2024
1 parent 40a80c7 commit df53676
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 39 deletions.
3 changes: 2 additions & 1 deletion src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ public enum ErrorCodes {
BARCODE_IS_NOT_UNIQUE("barcodeIsNotUnique", "The barcode already exists. The barcode must be unique"),
DELETE_WITH_EXPENDED_AMOUNT("deleteWithExpendedAmount", "Cannot delete an encumbrance with an expended amount"),
INVALID_ROUTING_LIST_FOR_PO_LINE_FORMAT("invalidRoutingListForPoLineFormat", "Cannot create routing list for POL without 'Physical' or 'P/E Mix' order format"),
ROUTING_LIST_LIMIT_REACHED_FOR_PO_LINE("routingListLimitReachedForPoLine", "Cannot create routing list for POL as the associated lists' amount is not less than Physical copies");
ROUTING_LIST_LIMIT_REACHED_FOR_PO_LINE("routingListLimitReachedForPoLine", "Cannot create routing list for POL as the associated lists' amount is not less than Physical copies"),
PO_LINE_NOT_FOUND_FOR_ROUTING_LIST("poLineNotFoundForRoutingList", "Cannot find a corresponding PO Line with the provided id");

private final String code;
private final String description;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/folio/rest/impl/RoutingListsAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void deleteOrdersRoutingListsById(String id, Map<String, String> okapiHea
@Validate
public void putOrdersRoutingListsById(String id, RoutingList entity, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
routingListService.updateRoutingList(entity, new RequestContext(vertxContext, okapiHeaders))
.onSuccess(list -> asyncResultHandler.handle(succeededFuture(buildOkResponse(list))))
.onSuccess(list -> asyncResultHandler.handle(succeededFuture(buildNoContentResponse())))
.onFailure(fail -> handleErrorResponse(asyncResultHandler, fail));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,14 @@ public Future<RoutingList> getRoutingList(String rListId, RequestContext request
}

public Future<Void> updateRoutingList(RoutingList routingList, RequestContext requestContext) {
validateRoutingList(routingList, requestContext);
try {
validateRoutingList(routingList, requestContext);
}
catch (HttpException e) {
return Future.failedFuture(e);
}
RequestEntry requestEntry = new RequestEntry(ROUTING_LIST_BY_ID_ENDPOINT).withId(routingList.getId());
return restClient.put(requestEntry, requestContext, requestContext);
return restClient.put(requestEntry, routingList, requestContext);
}

public Future<Void> deleteRoutingList(String rListId, RequestContext requestContext) {
Expand All @@ -75,7 +80,11 @@ public Future<Void> deleteRoutingList(String rListId, RequestContext requestCont
}

public Future<RoutingList> createRoutingList(RoutingList routingList, RequestContext requestContext) {
validateRoutingList(routingList, requestContext);
try {
validateRoutingList(routingList, requestContext);
} catch (HttpException e) {
return Future.failedFuture(e);
}
RequestEntry requestEntry = new RequestEntry(ROUTING_LIST_ENDPOINT);
return restClient.post(requestEntry, routingList, RoutingList.class, requestContext);
}
Expand All @@ -93,7 +102,7 @@ private Future<RoutingListCollection> getRoutingListsByPoLineId(String poLineId,
return getRoutingLists(Integer.MAX_VALUE, 0, query, requestContext);
}

private void validateRoutingList(RoutingList routingList, RequestContext requestContext) {
private void validateRoutingList(RoutingList routingList, RequestContext requestContext) throws HttpException {
RoutingListCollection routingLists = getRoutingListsByPoLineId(routingList.getPoLineId(), requestContext).result();
PoLine poLine = poLineService.getOrderLineById(routingList.getPoLineId(), requestContext).result();
List<Error> combinedErrors = RoutingListValidatorUtil.validateRoutingList(routingLists, poLine);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ public class RoutingListValidatorUtil {

public static List<Error> validateRoutingList(RoutingListCollection rListExisting, PoLine poLine) {
List<ErrorCodes> errors = new ArrayList<>();
if (!isPoLineFormatValid(poLine)) {
if (poLine == null) {
errors.add(ErrorCodes.PO_LINE_NOT_FOUND_FOR_ROUTING_LIST);
} else if (!isPoLineFormatValid(poLine)) {
errors.add(ErrorCodes.INVALID_ROUTING_LIST_FOR_PO_LINE_FORMAT);
} else if (isRoutingListsLimitReached(rListExisting, poLine)) {
errors.add(ErrorCodes.ROUTING_LIST_LIMIT_REACHED_FOR_PO_LINE);
Expand Down
85 changes: 53 additions & 32 deletions src/test/java/org/folio/rest/impl/RoutingListsApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
import org.apache.logging.log4j.Logger;
import org.folio.ApiTestSuite;
import org.folio.HttpStatus;
import org.folio.rest.RestConstants;
import org.folio.rest.core.exceptions.ErrorCodes;
import org.folio.rest.core.exceptions.HttpException;
import org.folio.rest.core.models.RequestContext;
import org.folio.rest.jaxrs.model.RoutingList;
import org.folio.rest.jaxrs.model.RoutingListCollection;
import org.folio.rest.jaxrs.model.Error;
import org.folio.rest.jaxrs.model.Errors;
import org.folio.rest.jaxrs.model.PoLine;
import org.folio.service.orders.PurchaseOrderLineService;
import org.folio.service.routinglists.RoutingListService;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
Expand All @@ -23,12 +25,14 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

import static io.vertx.core.Future.failedFuture;
import static io.vertx.core.Future.succeededFuture;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.folio.RestTestUtils.prepareHeaders;
Expand Down Expand Up @@ -57,8 +61,11 @@
import static org.folio.TestUtils.getMinimalContentPoLine;
import static org.folio.TestUtils.getMockAsJson;
import static org.folio.orders.utils.ResourcePathResolver.PO_LINES_STORAGE;
import static org.folio.rest.RestConstants.BAD_REQUEST;
import static org.folio.rest.RestConstants.NOT_FOUND;
import static org.folio.rest.RestConstants.OKAPI_URL;
import static org.folio.rest.core.exceptions.ErrorCodes.INVALID_ROUTING_LIST_FOR_PO_LINE_FORMAT;
import static org.folio.rest.core.exceptions.ErrorCodes.PO_LINE_NOT_FOUND_FOR_ROUTING_LIST;
import static org.folio.rest.core.exceptions.ErrorCodes.ROUTING_LIST_LIMIT_REACHED_FOR_PO_LINE;
import static org.folio.rest.impl.MockServer.ROUTING_LISTS_MOCK_DATA_PATH;
import static org.folio.rest.impl.MockServer.addMockEntry;
Expand All @@ -67,6 +74,7 @@
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
Expand All @@ -87,11 +95,11 @@ public class RoutingListsApiTest {

@Autowired
private RoutingListService routingListService;
private PurchaseOrderLineService purchaseOrderLineService;
private RequestContext requestContext;
private Context ctxMock;
private Map<String, String> okapiHeadersMock;
private AutoCloseable mockitoMocks;
private RoutingList sampleRoutingList;

@BeforeAll
static void before() throws InterruptedException, ExecutionException, TimeoutException {
Expand All @@ -113,6 +121,8 @@ void beforeEach() {
okapiHeadersMock.put(X_OKAPI_TENANT.getName(), X_OKAPI_TENANT.getValue());
okapiHeadersMock.put(X_OKAPI_USER_ID.getName(), X_OKAPI_USER_ID.getValue());
requestContext = new RequestContext(ctxMock, okapiHeadersMock);
sampleRoutingList = routingListJsonReqData.mapTo(RoutingList.class)
.withPoLineId(PO_LINE_UUID);
}


Expand All @@ -139,11 +149,10 @@ void testPostRoutingList() {
.withLocations(getLocationPhysicalCopies(1));
addMockEntry(PO_LINES_STORAGE, JsonObject.mapFrom(poLine));

RoutingList rListRq = routingListJsonReqData.mapTo(RoutingList.class)
.withPoLineId(PO_LINE_UUID);
doReturn(succeededFuture(sampleRoutingList)).when(routingListService).createRoutingList(eq(sampleRoutingList), any(RequestContext.class));

verifyPostResponse(ROUTING_LISTS_ENDPOINT, JsonObject.mapFrom(rListRq).encode(),
prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, X_OKAPI_USER_ID_WITH_ACQ_UNITS), APPLICATION_JSON, HttpStatus.HTTP_CREATED.toInt());
verifyPostResponse(ROUTING_LISTS_ENDPOINT, JsonObject.mapFrom(sampleRoutingList).encode(),
prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, X_OKAPI_USER_ID_WITH_ACQ_UNITS), APPLICATION_JSON, HttpStatus.HTTP_OK.toInt());
}

@Test
Expand All @@ -155,10 +164,10 @@ void testPostRoutingListShouldFailForInvalidOrderType() {
.withOrderFormat(PoLine.OrderFormat.ELECTRONIC_RESOURCE);
addMockEntry(PO_LINES_STORAGE, JsonObject.mapFrom(poLine));

RoutingList rListRq = routingListJsonReqData.mapTo(RoutingList.class)
.withPoLineId(PO_LINE_UUID);
var errorsExpected = getCodesAsErrors(INVALID_ROUTING_LIST_FOR_PO_LINE_FORMAT);
doReturn(failedFuture(new HttpException(RestConstants.VALIDATION_ERROR, errorsExpected))).when(routingListService).createRoutingList(eq(sampleRoutingList), any(RequestContext.class));

List<Error> errors = verifyPostResponse(ROUTING_LISTS_ENDPOINT, JsonObject.mapFrom(rListRq).encode(),
List<Error> errors = verifyPostResponse(ROUTING_LISTS_ENDPOINT, JsonObject.mapFrom(sampleRoutingList).encode(),
prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, X_OKAPI_USER_ID), APPLICATION_JSON, 422)
.as(Errors.class)
.getErrors();
Expand All @@ -176,10 +185,10 @@ void testPostRoutingListShouldFailForLimitReached() {
.withLocations(getLocationPhysicalCopies(0));
addMockEntry(PO_LINES_STORAGE, JsonObject.mapFrom(poLine));

RoutingList rListRq = routingListJsonReqData.mapTo(RoutingList.class)
.withPoLineId(PO_LINE_UUID);
var errorsExpected = getCodesAsErrors(ROUTING_LIST_LIMIT_REACHED_FOR_PO_LINE);
doReturn(failedFuture(new HttpException(RestConstants.VALIDATION_ERROR, errorsExpected))).when(routingListService).createRoutingList(eq(sampleRoutingList), any(RequestContext.class));

List<Error> errors = verifyPostResponse(ROUTING_LISTS_ENDPOINT, JsonObject.mapFrom(rListRq).encode(),
List<Error> errors = verifyPostResponse(ROUTING_LISTS_ENDPOINT, JsonObject.mapFrom(sampleRoutingList).encode(),
prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, X_OKAPI_USER_ID), APPLICATION_JSON, 422
)
.as(Errors.class)
Expand All @@ -192,16 +201,25 @@ void testPostRoutingListShouldFailForLimitReached() {
void testPostRoutingListWithInvalidPoLineId() {
logger.info("=== Test POST Routing List should fail because it's POL does not exist ===");

RoutingList rListRq = routingListJsonReqData.mapTo(RoutingList.class)
.withPoLineId(PO_LINE_UUID);
var errorsExpected = getCodesAsErrors(PO_LINE_NOT_FOUND_FOR_ROUTING_LIST);
doReturn(failedFuture(new HttpException(RestConstants.VALIDATION_ERROR, errorsExpected))).when(routingListService).createRoutingList(eq(sampleRoutingList), any(RequestContext.class));

List<Error> errors = verifyPostResponse(ROUTING_LISTS_ENDPOINT, JsonObject.mapFrom(sampleRoutingList).encode(),
prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, X_OKAPI_USER_ID), APPLICATION_JSON, 422
)
.as(Errors.class)
.getErrors();

verifyPostResponse(ROUTING_LISTS_ENDPOINT, JsonObject.mapFrom(rListRq).encode(),
prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, X_OKAPI_USER_ID), APPLICATION_JSON, 404);
assertThat(errors.get(0).getMessage(), equalTo(PO_LINE_NOT_FOUND_FOR_ROUTING_LIST.getDescription()));
}

@Test
void testGetRoutingLists() {
logger.info("=== Test Get Routing Lists ===");
var collection = new RoutingListCollection()
.withRoutingLists(List.of(sampleRoutingList))
.withTotalRecords(1);
doReturn(succeededFuture(collection)).when(routingListService).getRoutingLists(anyInt(), anyInt(), any(), any(RequestContext.class));

final RoutingListCollection respCollection = verifySuccessGet(ROUTING_LISTS_ENDPOINT, RoutingListCollection.class);
logger.info(JsonObject.mapFrom(respCollection).encodePrettily());
Expand All @@ -210,7 +228,8 @@ void testGetRoutingLists() {

@Test
void testGetRoutingListById() {
logger.info("=== Test Get Routing Lists ===");
logger.info("=== Test Get Routing List by id ===");
doReturn(succeededFuture(sampleRoutingList)).when(routingListService).getRoutingList(eq(ROUTING_LIST_UUID), any(RequestContext.class));

final RoutingList resp = verifySuccessGet(String.format(ROUTING_LISTS_ID_PATH, ROUTING_LIST_UUID), RoutingList.class);
logger.info(JsonObject.mapFrom(resp).encodePrettily());
Expand All @@ -220,38 +239,34 @@ void testGetRoutingListById() {
@Test
void testPutRoutingList() {
logger.info("=== Test update Routing List by id ===");
RoutingList reqData = routingListJsonReqData.mapTo(RoutingList.class)
.withNotes("new notes");
sampleRoutingList.setNotes("new notes");
doReturn(succeededFuture()).when(routingListService).updateRoutingList(eq(sampleRoutingList), any(RequestContext.class));

verifyPut(String.format(ROUTING_LISTS_ID_PATH, ROUTING_LIST_UUID), JsonObject.mapFrom(reqData).encode(),
verifyPut(String.format(ROUTING_LISTS_ID_PATH, ROUTING_LIST_UUID), JsonObject.mapFrom(sampleRoutingList).encode(),
prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10), "", 204);
}

@Test
void testPutRoutingListByNonExistentId() {
logger.info("=== Test update Routing List by invalid id ===");

RoutingList reqData = routingListJsonReqData.mapTo(RoutingList.class)
.withId(ID_DOES_NOT_EXIST);
verifyPut(String.format(ROUTING_LISTS_ID_PATH, ID_DOES_NOT_EXIST), JsonObject.mapFrom(reqData).encode(), APPLICATION_JSON, 404);
}

@Test
void deleteRoutingListByIdTest() {
void testDeleteRoutingListByIdTest() {
logger.info("=== Test delete Routing List by id ===");
doReturn(succeededFuture()).when(routingListService).deleteRoutingList(eq(ROUTING_LIST_UUID), any(RequestContext.class));

verifyDeleteResponse(String.format(ROUTING_LISTS_ID_PATH, ROUTING_LIST_UUID), "", 204);
}

@Test
void deleteRoutingListByIdWithInvalidFormatTest() {
void testDeleteRoutingListByIdWithInvalidFormatTest() {
logger.info("=== Test delete Routing List by id ===");
doReturn(failedFuture(new HttpException(BAD_REQUEST, ErrorCodes.GENERIC_ERROR_CODE))).when(routingListService).deleteRoutingList(eq(ID_BAD_FORMAT), any(RequestContext.class));

verifyDeleteResponse(String.format(ROUTING_LISTS_ID_PATH, ID_BAD_FORMAT), APPLICATION_JSON, 400);
}

@Test
void deleteNotExistentRoutingListTest() {
void testDeleteNotExistentRoutingListTest() {
logger.info("=== Test delete Routing List by id ===");
doReturn(failedFuture(new HttpException(NOT_FOUND, ErrorCodes.GENERIC_ERROR_CODE))).when(routingListService).deleteRoutingList(eq(ID_DOES_NOT_EXIST), any(RequestContext.class));

verifyDeleteResponse(String.format(ROUTING_LISTS_ID_PATH, ID_DOES_NOT_EXIST), APPLICATION_JSON, 404);
}

Expand All @@ -267,6 +282,12 @@ void testProcessTemplateRequest() {
verify(routingListService, times(1)).processTemplateRequest(eq(ROUTING_LIST_ID), any(RequestContext.class));
}

private Errors getCodesAsErrors(ErrorCodes... codes) {
return new Errors()
.withErrors(Arrays.stream(codes).map(ErrorCodes::toError).toList())
.withTotalRecords(codes.length);
}

static class ContextConfiguration {

@Bean
Expand Down

0 comments on commit df53676

Please sign in to comment.