-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MODORDER-1087]-Delete received pieces in bulk #952
base: master
Are you sure you want to change the base?
Changes from 7 commits
55b0a7a
6db3963
8771a90
3ab692c
ad25b1a
0bf580a
7981d47
b4a0f4d
5ced63d
03aa3cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,13 +33,16 @@ | |
import static org.hamcrest.Matchers.nullValue; | ||
import static org.junit.jupiter.api.Assertions.assertNull; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.UUID; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.TimeoutException; | ||
|
||
import io.restassured.http.Header; | ||
import io.vertx.core.json.JsonArray; | ||
import io.vertx.core.json.JsonObject; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
|
@@ -55,6 +58,7 @@ | |
import org.folio.rest.jaxrs.model.Location; | ||
import org.folio.rest.jaxrs.model.Physical; | ||
import org.folio.rest.jaxrs.model.Piece; | ||
import org.folio.rest.jaxrs.model.PieceCollection; | ||
import org.folio.rest.jaxrs.model.PurchaseOrder; | ||
import org.folio.rest.jaxrs.model.Title; | ||
import org.junit.jupiter.api.AfterAll; | ||
|
@@ -70,6 +74,8 @@ public class PieceApiTest { | |
private static final String PIECES_ID_PATH = PIECES_ENDPOINT + "/%s"; | ||
static final String CONSISTENT_RECEIVED_STATUS_PIECE_UUID = "7d0aa803-a659-49f0-8a95-968f277c87d7"; | ||
private JsonObject pieceJsonReqData = getMockAsJson(PIECE_RECORDS_MOCK_DATA_PATH + "pieceRecord.json"); | ||
public static final String PIECES_BATCH_DELETE_ENDPOINT = "orders/pieces/batch"; | ||
|
||
|
||
private static boolean runningOnOwn; | ||
|
||
|
@@ -356,4 +362,95 @@ void deletePieceInternalErrorOnStorageTest() { | |
logger.info("=== Test delete piece by id - internal error from storage 500 ==="); | ||
verifyDeleteResponse(String.format(PIECES_ID_PATH, ID_FOR_INTERNAL_SERVER_ERROR), APPLICATION_JSON, 500); | ||
} | ||
|
||
@Test | ||
void deletePiecesByIdsTest2() { | ||
logger.info("=== Test delete pieces by ids - item deleted ==="); | ||
|
||
String pieceId = UUID.randomUUID().toString(); | ||
List<String> ids = Arrays.asList(pieceId); | ||
Boolean deleteHoldings = false; | ||
JsonArray jsonArrary = new JsonArray(ids); | ||
JsonObject jsonObject = new JsonObject() | ||
.put("ids", jsonArrary); | ||
// .put("deleteHolding", deleteHoldings); | ||
|
||
List <Piece> pieces = new ArrayList<>(); | ||
|
||
|
||
// Mock response setup for deletion | ||
//MockServer.addMockEntry(PIECES_STORAGE, JsonObject.mapFrom(jsonObject).encode()); // Simplified mock data | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also remove commentds, if it is not helpful There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thank you for pointing it out ! will do |
||
|
||
// Simulate the delete call | ||
verifyDeleteResponse(PIECES_BATCH_DELETE_ENDPOINT, | ||
String.valueOf(jsonObject), | ||
prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, X_OKAPI_USER_ID), | ||
APPLICATION_JSON, 204); // Assuming successful deletion returns a 204 No Content | ||
|
||
// Assertions to check that the deletion was processed in the mock server | ||
assertNull(MockServer.getItemDeletions()); // Check if item deletions are as expected | ||
assertThat(MockServer.getPieceDeletions(), hasSize(1)); // Verify that exactly one piece deletion was processed | ||
} | ||
|
||
@Test | ||
public void deletePiecesByIdsTest() { | ||
logger.info("=== Test delete pieces by ids - item deleted ==="); | ||
|
||
// Create unique IDs for the components | ||
String itemId = UUID.randomUUID().toString(); | ||
String lineId = UUID.randomUUID().toString(); | ||
String orderId = UUID.randomUUID().toString(); | ||
String holdingId = UUID.randomUUID().toString(); | ||
String titleId = UUID.randomUUID().toString(); | ||
|
||
CompositePurchaseOrder order = new CompositePurchaseOrder().withId(orderId); | ||
Location loc = new Location().withHoldingId(holdingId).withQuantityElectronic(1).withQuantity(1); | ||
Cost cost = new Cost().withQuantityElectronic(1); | ||
|
||
// Setup the PO Line | ||
CompositePoLine poLine = new CompositePoLine().withId(lineId) | ||
.withOrderFormat(CompositePoLine.OrderFormat.PHYSICAL_RESOURCE) | ||
.withLocations(Collections.singletonList(loc)) | ||
.withCost(cost) | ||
.withPhysical(new Physical().withCreateInventory(Physical.CreateInventory.INSTANCE_HOLDING_ITEM)); | ||
|
||
order.setCompositePoLines(Collections.singletonList(poLine)); | ||
|
||
// Create a title | ||
Title title = new Title().withId(titleId).withTitle("title name"); | ||
|
||
// Setup the piece | ||
Piece piece = new Piece().withId(UUID.randomUUID().toString()) | ||
.withFormat(Piece.Format.PHYSICAL) | ||
.withHoldingId(holdingId) | ||
.withItemId(itemId) | ||
.withPoLineId(poLine.getId()) | ||
.withTitleId(titleId); | ||
|
||
// Mock the server responses | ||
MockServer.addMockEntry(PIECES_STORAGE, JsonObject.mapFrom(piece)); | ||
MockServer.addMockEntry(PO_LINES_STORAGE, JsonObject.mapFrom(poLine)); | ||
MockServer.addMockEntry(PURCHASE_ORDER_STORAGE, JsonObject.mapFrom(order)); | ||
MockServer.addMockEntry(TITLES, JsonObject.mapFrom(title)); | ||
MockServer.addMockEntry(ITEM_RECORDS, new JsonObject().put(ID, itemId)); | ||
|
||
// Prepare request data as JSON Array | ||
JsonArray jsonArray = new JsonArray().add(piece.getId()); | ||
JsonObject jsonObject = new JsonObject() | ||
.put("ids", jsonArray) | ||
.put("deleteHoldings", false); | ||
|
||
// Log the JSON being sent to the server | ||
logger.debug("Sending JSON for deletion: {}", jsonObject.encode()); | ||
|
||
// Perform the delete operation and verify the response | ||
verifyDeleteResponse(PIECES_BATCH_DELETE_ENDPOINT, jsonObject.toString(), | ||
prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, X_OKAPI_USER_ID), APPLICATION_JSON, 204).as(Piece.class); | ||
|
||
// Assert no items were deleted | ||
assertNull(MockServer.getItemDeletions()); | ||
|
||
// Assert that exactly one piece was deleted | ||
assertThat(MockServer.getPieceDeletions(), hasSize(1)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
package org.folio.service.pieces.flows.delete; | ||
|
||
import static io.vertx.core.Future.*; | ||
import static io.vertx.core.Future.succeededFuture; | ||
import static org.folio.TestConfig.autowireDependencies; | ||
import static org.folio.TestConfig.clearServiceInteractions; | ||
|
@@ -42,6 +43,7 @@ | |
import org.folio.rest.jaxrs.model.Eresource; | ||
import org.folio.rest.jaxrs.model.Location; | ||
import org.folio.rest.jaxrs.model.Piece; | ||
import org.folio.rest.jaxrs.model.PieceCollection; | ||
import org.folio.rest.jaxrs.model.PoLine; | ||
import org.folio.rest.jaxrs.model.PurchaseOrder; | ||
import org.folio.rest.jaxrs.model.Title; | ||
|
@@ -368,6 +370,67 @@ void shouldUpdateLineQuantityIfPoLineIsNotPackageAndManualPieceCreateFalseAndInv | |
verify(basePieceFlowHolderBuilder).updateHolderWithOrderInformation(holder, requestContext); | ||
} | ||
|
||
@Test | ||
void shouldDeletePiecesInBatch() { | ||
String orderId = UUID.randomUUID().toString(); | ||
String holdingId = UUID.randomUUID().toString(); | ||
String lineId = UUID.randomUUID().toString(); | ||
String itemId = UUID.randomUUID().toString(); | ||
String locationId = UUID.randomUUID().toString(); | ||
String titleId = UUID.randomUUID().toString(); | ||
JsonObject holding = new JsonObject(); | ||
holding.put(ID, holdingId); | ||
holding.put(HOLDING_PERMANENT_LOCATION_ID, locationId); | ||
JsonObject item = new JsonObject().put(ID, itemId); | ||
item.put(ITEM_STATUS, new JsonObject().put(ITEM_STATUS_NAME, ItemStatus.ON_ORDER.value())); | ||
Piece piece = new Piece().withId(UUID.randomUUID().toString()).withPoLineId(lineId) | ||
.withHoldingId(holdingId).withFormat(Piece.Format.ELECTRONIC); | ||
Location loc = new Location().withHoldingId(holdingId).withQuantityElectronic(1).withQuantity(1); | ||
Cost cost = new Cost().withQuantityElectronic(1) | ||
.withListUnitPriceElectronic(1d).withExchangeRate(1d).withCurrency("USD") | ||
.withPoLineEstimatedPrice(1d); | ||
PoLine poLine = new PoLine().withIsPackage(false).withCheckinItems(false).withOrderFormat(PoLine.OrderFormat.ELECTRONIC_RESOURCE) | ||
.withEresource(new Eresource().withCreateInventory(Eresource.CreateInventory.INSTANCE_HOLDING)) | ||
.withPurchaseOrderId(orderId).withId(lineId).withLocations(List.of(loc)).withCost(cost); | ||
PurchaseOrder purchaseOrder = new PurchaseOrder().withId(orderId).withWorkflowStatus(PurchaseOrder.WorkflowStatus.OPEN); | ||
Title title = new Title().withId(titleId); | ||
List<Piece> pieces = new ArrayList<>(); | ||
pieces.add(piece); | ||
List<String> ids = new ArrayList<>(); | ||
ids.add(piece.getId()); | ||
doReturn(succeededFuture(piece)).when(pieceStorageService).getPieceById(piece.getId(), requestContext); | ||
doReturn(succeededFuture(null)).when(protectionService).isOperationRestricted(any(), any(ProtectedOperationType.class), eq(requestContext)); | ||
doReturn(succeededFuture(null)).when(pieceStorageService).deletePiece(eq(piece.getId()), eq(true), eq(requestContext)); | ||
doReturn(succeededFuture(null)).when(circulationRequestsRetriever).getNumberOfRequestsByItemId(eq(piece.getItemId()), eq(requestContext)); | ||
doReturn(succeededFuture(holding)).when(inventoryHoldingManager).getHoldingById(holdingId, false, requestContext); | ||
doReturn(succeededFuture(null)).when(inventoryItemManager).getItemsByHoldingId(holdingId, requestContext); | ||
doReturn(succeededFuture(null)).when(inventoryHoldingManager).deleteHoldingById(piece.getHoldingId(), true, requestContext); | ||
doReturn(succeededFuture(null)).when(inventoryItemManager).getItemRecordById(itemId, true, requestContext); | ||
doReturn(succeededFuture(null)).when(inventoryItemManager).deleteItem(itemId, true, requestContext); | ||
doReturn(succeededFuture(holding)).when(inventoryHoldingManager).getHoldingById(holdingId, true, requestContext); | ||
doReturn(succeededFuture(null)).when(pieceUpdateInventoryService).deleteHoldingConnectedToPiece(piece, requestContext); | ||
doReturn(succeededFuture(new ArrayList<JsonObject>())).when(inventoryItemManager).getItemsByHoldingId(holdingId, requestContext); | ||
final ArgumentCaptor<PieceDeletionHolder> PieceDeletionHolderCapture = ArgumentCaptor.forClass(PieceDeletionHolder.class); | ||
doAnswer((Answer<Future<Void>>) invocation -> { | ||
PieceDeletionHolder answerHolder = invocation.getArgument(0); | ||
answerHolder.withOrderInformation(purchaseOrder, poLine); | ||
return succeededFuture(null); | ||
}).when(basePieceFlowHolderBuilder).updateHolderWithOrderInformation(PieceDeletionHolderCapture.capture(), eq(requestContext)); | ||
doAnswer((Answer<Future<Void>>) invocation -> { | ||
PieceDeletionHolder answerHolder = invocation.getArgument(0); | ||
answerHolder.withTitleInformation(title); | ||
return succeededFuture(null); | ||
}).when(basePieceFlowHolderBuilder).updateHolderWithTitleInformation(PieceDeletionHolderCapture.capture(), eq(requestContext)); | ||
|
||
final ArgumentCaptor<PieceDeletionHolder> pieceDeletionHolderCapture = ArgumentCaptor.forClass(PieceDeletionHolder.class); | ||
doReturn(succeededFuture(null)).when(pieceDeleteFlowPoLineService).updatePoLine(pieceDeletionHolderCapture.capture(), eq(requestContext)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also separate declaration doReturn and action and verification part to be easy to read |
||
//When | ||
pieceDeleteFlowManager.batchDeletePiece(ids,false ,requestContext).result(); | ||
verify(pieceStorageService).deletePiece(eq(piece.getId()), eq(true), eq(requestContext)); | ||
verify(inventoryItemManager, times(0)).deleteItem(itemId, true, requestContext); | ||
verify(pieceStorageService, times(1)).deletePiece(eq(piece.getId()), eq(true), eq(requestContext)); | ||
} | ||
|
||
private static class ContextConfiguration { | ||
|
||
@Bean | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Piece records
orPieces
more correctThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also refactor Sentences in other places to be gramatically correct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you, sure will.