From 42738a1f079da17b3cf00aeff37e186e82f4c31c Mon Sep 17 00:00:00 2001 From: OleksandrVidinieiev <56632770+OleksandrVidinieiev@users.noreply.github.com> Date: Tue, 31 Oct 2023 19:19:21 +0200 Subject: [PATCH] CIRC-1769: Add support for Actual Cost Records properties lost in deserialization (#1356) * CIRC-1769 Add missing properties to POJO->JSON conversion * CIRC-1769 Replace Collectors#toList with Stream#toList * CIRC-1769 API test * CIRC-1769 Refactor test --- .../mappers/ActualCostRecordMapper.java | 25 +++++-- ...piredActualCostRecordsProcessingTests.java | 13 ++++ .../mappers/ActualCostRecordMapperTest.java | 73 +++++++++++++++++++ 3 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 src/test/java/org/folio/circulation/storage/mappers/ActualCostRecordMapperTest.java diff --git a/src/main/java/org/folio/circulation/storage/mappers/ActualCostRecordMapper.java b/src/main/java/org/folio/circulation/storage/mappers/ActualCostRecordMapper.java index 12bd59eba7..ecc59157c3 100644 --- a/src/main/java/org/folio/circulation/storage/mappers/ActualCostRecordMapper.java +++ b/src/main/java/org/folio/circulation/storage/mappers/ActualCostRecordMapper.java @@ -9,7 +9,7 @@ import static org.folio.circulation.support.json.JsonPropertyFetcher.getProperty; import static org.folio.circulation.support.json.JsonPropertyWriter.write; -import java.util.stream.Collectors; +import java.util.Collection; import org.folio.circulation.domain.ActualCostRecord; import org.folio.circulation.domain.ActualCostRecord.ActualCostRecordFeeFine; @@ -21,6 +21,7 @@ import org.folio.circulation.domain.CallNumberComponents; import org.folio.circulation.domain.ItemLossType; +import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; public class ActualCostRecordMapper { @@ -30,6 +31,7 @@ private ActualCostRecordMapper() { public static JsonObject toJson(ActualCostRecord actualCostRecord) { JsonObject json = new JsonObject(); + write(json, "id", actualCostRecord.getId()); write(json, "lossType", actualCostRecord.getLossType().getValue()); write(json, "lossDate", actualCostRecord.getLossDate()); write(json, "expirationDate", actualCostRecord.getExpirationDate()); @@ -53,7 +55,6 @@ public static JsonObject toJson(ActualCostRecord actualCostRecord) { ActualCostRecordLoan loan = actualCostRecord.getLoan(); if (loan != null) { write(loanJson, "id", loan.getId()); - write(json, "loan", loanJson); } @@ -86,7 +87,7 @@ public static JsonObject toJson(ActualCostRecord actualCostRecord) { if (item != null) { write(instanceJson, "id", instance.getId()); write(instanceJson, "title", instance.getTitle()); - write(instanceJson, "identifiers", instance.getIdentifiers()); + write(instanceJson, "identifiers", mapIdentifiersToJson(instance.getIdentifiers())); write(instanceJson, "contributors", mapContributorNamesToJson(instance.getContributors())); write(json, "instance", instanceJson); @@ -131,7 +132,9 @@ public static ActualCostRecord toDomain(JsonObject representation) { .withBarcode(getProperty(user, "barcode")) .withFirstName(getProperty(user, "firstName")) .withLastName(getProperty(user, "lastName")) - .withMiddleName(getProperty(user, "middleName")), + .withMiddleName(getProperty(user, "middleName")) + .withPatronGroup(getProperty(user, "patronGroup")) + .withPatronGroupId(getProperty(user, "patronGroupId")), new ActualCostRecordLoan() .withId(getProperty(loan, "id")), new ActualCostRecordItem() @@ -146,6 +149,10 @@ public static ActualCostRecord toDomain(JsonObject representation) { .withLoanTypeId(getProperty(item, "loanTypeId")) .withLoanType(getProperty(item, "loanType")) .withHoldingsRecordId(getProperty(item, "holdingsRecordId")) + .withVolume(getProperty(item, "volume")) + .withEnumeration(getProperty(item, "enumeration")) + .withChronology(getProperty(item, "chronology")) + .withCopyNumber(getProperty(item, "copyNumber")) .withEffectiveCallNumberComponents(CallNumberComponents.fromItemJson(item)), new ActualCostRecordInstance() .withId(getProperty(instance, "id")) @@ -153,11 +160,11 @@ public static ActualCostRecord toDomain(JsonObject representation) { .withIdentifiers(getArrayProperty(instance, "identifiers").stream() .map(JsonObject.class::cast) .map(ActualCostRecordIdentifier::fromRepresentation) - .collect(Collectors.toList())) + .toList()) .withContributors(getArrayProperty(instance, "contributors").stream() .map(JsonObject.class::cast) .map(new ContributorMapper()::toDomain) - .collect(Collectors.toList())), + .toList()), new ActualCostRecordFeeFine() .withAccountId(getProperty(feeFine, "accountId")) .withOwnerId(getProperty(feeFine, "ownerId")) @@ -166,4 +173,10 @@ public static ActualCostRecord toDomain(JsonObject representation) { .withType(getProperty(feeFine, "type")), getNestedDateTimeProperty(representation, "metadata", "createdDate")); } + + private static JsonArray mapIdentifiersToJson(Collection identifiers) { + return new JsonArray(identifiers.stream() + .map(JsonObject::mapFrom) + .toList()); + } } diff --git a/src/test/java/api/loans/ExpiredActualCostRecordsProcessingTests.java b/src/test/java/api/loans/ExpiredActualCostRecordsProcessingTests.java index fe22e218de..629f6f0bbb 100644 --- a/src/test/java/api/loans/ExpiredActualCostRecordsProcessingTests.java +++ b/src/test/java/api/loans/ExpiredActualCostRecordsProcessingTests.java @@ -8,6 +8,7 @@ import static org.folio.circulation.domain.ActualCostRecord.Status.EXPIRED; import static org.folio.circulation.domain.ActualCostRecord.Status.OPEN; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.params.provider.EnumSource.Mode.EXCLUDE; @@ -124,6 +125,18 @@ void multipleOpenExpiredActualCostRecordsAreProcessed() { assertThatLoanIsClosedAsLostAndPaid(thirdRecord); } + @Test + void expiredRecordHasSamePropertiesAsOriginalOpenRecord() { + JsonObject openRecord = generateActualCostRecord(OPEN); + UUID recordId = UUID.fromString(openRecord.getString("id")); + runProcessingAfterExpirationDate(); + JsonObject expiredRecord = actualCostRecordsClient.getById(recordId).getJson(); + assertThat(expiredRecord, isInStatus(EXPIRED)); + openRecord.putNull("metadata"); + expiredRecord.putNull("metadata"); + assertThat(openRecord.put("status", "Expired"), equalTo(expiredRecord)); + } + private void assertThatActualCostRecordIsInStatus(JsonObject actualCostRecord, ActualCostRecord.Status status) { diff --git a/src/test/java/org/folio/circulation/storage/mappers/ActualCostRecordMapperTest.java b/src/test/java/org/folio/circulation/storage/mappers/ActualCostRecordMapperTest.java new file mode 100644 index 0000000000..35dc4b37d2 --- /dev/null +++ b/src/test/java/org/folio/circulation/storage/mappers/ActualCostRecordMapperTest.java @@ -0,0 +1,73 @@ +package org.folio.circulation.storage.mappers; + +import static org.folio.circulation.storage.mappers.ActualCostRecordMapper.toDomain; +import static org.folio.circulation.storage.mappers.ActualCostRecordMapper.toJson; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +class ActualCostRecordMapperTest { + + @Test + void mappingTest() { + JsonObject actualCostRecordJson = new JsonObject() + .put("id", "c98215a8-987a-4ccd-9f3e-17b2f468d487") + .put("lossType", "Declared lost") + .put("lossDate", "2023-10-30T11:22:23.053Z") + .put("expirationDate", "2023-10-30T11:22:23.053Z") + .put("status", "Billed") + .put("user", new JsonObject() + .put("id", "72235d24-aead-4647-bad2-2febb12d940a") + .put("barcode", "1") + .put("firstName", "First") + .put("lastName", "Last") + .put("middleName", "Middle") + .put("patronGroupId", "503a81cd-6c26-400f-b620-14c08943697c") + .put("patronGroup", "Faculty")) + .put("loan", new JsonObject() + .put("id", "1e65b451-3cde-4575-93c1-9b7ff03db4fd")) + .put("item", new JsonObject() + .put("id", "bbe89d07-791a-48c5-86b1-79441f5fcd49") + .put("barcode", "abc123") + .put("materialTypeId", "d9acad2f-2aac-4b48-9097-e6ab85906b25") + .put("materialType", "text") + .put("permanentLocationId", "fcd64ce1-6995-48f0-840e-89ffa2288371") + .put("permanentLocation", "Main Library") + .put("effectiveLocationId", "a2a89dec-522b-4c1d-9690-a2f922869e68") + .put("effectiveLocation", "Annex") + .put("loanTypeId", "2b94c631-fca9-4892-a730-03ee529ffe27") + .put("loanType", "Can circulate") + .put("holdingsRecordId", "e6d7e91a-4dbc-4a70-9b38-e000d2fbdc79") + .put("volume", "vol") + .put("enumeration", "enum") + .put("chronology", "chrono") + .put("copyNumber", "copy") + .put("effectiveCallNumberComponents", new JsonObject() + .put("callNumber", "CN") + .put("prefix", "PFX") + .put("suffix", "SFX"))) + .put("instance", new JsonObject() + .put("id", "cf23adf0-61ba-4887-bf82-956c4aae2260") + .put("title", "Test book") + .put("identifiers", new JsonArray() + .add(new JsonObject() + .put("value", "1447294130") + .put("identifierTypeId", "8261054f-be78-422d-bd51-4ed9f33c3422") + .put("identifierType", "ISBN"))) + .put("contributors", new JsonArray() + .add(new JsonObject() + .put("name", "Test, Author")))) + .put("feeFine", new JsonObject() + .put("accountId", "cdac704f-17aa-57fa-9500-607c5fa792bd") + .put("ownerId", "94aecb81-b025-4eca-9e0e-14756d052836") + .put("owner", "Test owner") + .put("typeId", "73785370-d3bd-4d92-942d-ae2268e02ded") + .put("type", "Lost item fee (actual cost)")); + + assertEquals(actualCostRecordJson, toJson(toDomain(actualCostRecordJson))); + } + +} \ No newline at end of file