From 1c374d850135bf87cb5826768d4954e10f6c860b Mon Sep 17 00:00:00 2001 From: Nate Harris Date: Fri, 12 Apr 2024 12:39:36 -0600 Subject: [PATCH 1/4] - Fix invalid schema for carrier account field/fields --- CHANGELOG.md | 4 ++ src/main/java/com/easypost/model/Field.java | 1 - src/main/java/com/easypost/model/Fields.java | 6 +++ src/test/java/com/easypost/BillingTest.java | 9 ---- .../java/com/easypost/CarrierAccountTest.java | 47 +++++++++++++++++++ 5 files changed, 57 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1191163da..99b8884b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## Next Release + +- Fix `Fields` serialization bug causing carrier account operations to fail + ## v7.2.0 (2024-04-10) - Adds `refund` function in Insurance service for requesting a refund for a standalone insurance diff --git a/src/main/java/com/easypost/model/Field.java b/src/main/java/com/easypost/model/Field.java index e344409ef..119ea847a 100644 --- a/src/main/java/com/easypost/model/Field.java +++ b/src/main/java/com/easypost/model/Field.java @@ -4,7 +4,6 @@ @Getter public class Field extends EasyPostResource { - private String key; private String visibility; private String label; private String value; diff --git a/src/main/java/com/easypost/model/Fields.java b/src/main/java/com/easypost/model/Fields.java index c9521e5df..c700389de 100644 --- a/src/main/java/com/easypost/model/Fields.java +++ b/src/main/java/com/easypost/model/Fields.java @@ -2,6 +2,12 @@ import lombok.Getter; +import java.util.Map; + @Getter public class Fields extends EasyPostResource { + private Map credentials; + private Map testCredentials; + private boolean autoLink; + private boolean customWorkflow; } diff --git a/src/test/java/com/easypost/BillingTest.java b/src/test/java/com/easypost/BillingTest.java index 9abd59b14..40ff321dc 100644 --- a/src/test/java/com/easypost/BillingTest.java +++ b/src/test/java/com/easypost/BillingTest.java @@ -25,15 +25,6 @@ public final class BillingTest { "ll,\"last4\":\"4444\",\"exp_month\":1,\"exp_year\":2025,\"brand\":\"Mastercard\"}}"; private PaymentMethod paymentMethod = Constants.Http.GSON.fromJson(jsonResponse, PaymentMethod.class); - private String jsonResponseLegacyPrefixes = "{\"id\":\"cust_...\",\"object\":\"PaymentMethods\",\"primary_" + - "payment_method\":{\"id\":\"card_...\",\"disabled_at\":null,\"object\":null,\"na" + - "me\":null,\"last4\":\"4242\",\"exp_month\":1,\"exp_year\":2025,\"brand\":\"Visa\"},\"secondar" + - "y_payment_method\":{\"id\":\"bank_...\",\"disabled_at\":null,\"object\":null,\"name\":nu" + - "ll,\"last4\":\"4444\",\"exp_month\":1,\"exp_year\":2025,\"brand\":\"Mastercard\"}}"; - - private PaymentMethod paymentMethodLegacyPrefixes = - Constants.Http.GSON.fromJson(jsonResponseLegacyPrefixes, PaymentMethod.class); - private static MockedStatic requestMock = Mockito.mockStatic(Requestor.class); /** diff --git a/src/test/java/com/easypost/CarrierAccountTest.java b/src/test/java/com/easypost/CarrierAccountTest.java index 21138884c..e920a5e3e 100644 --- a/src/test/java/com/easypost/CarrierAccountTest.java +++ b/src/test/java/com/easypost/CarrierAccountTest.java @@ -2,12 +2,18 @@ import com.easypost.exception.API.InvalidRequestError; import com.easypost.exception.EasyPostException; +import com.easypost.http.Requestor; import com.easypost.model.CarrierAccount; import com.easypost.model.CarrierType; +import com.easypost.model.PaymentMethod; +import com.easypost.model.Pickup; +import com.easypost.model.Shipment; import com.google.common.collect.ImmutableMap; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; import java.util.HashMap; import java.util.List; @@ -23,6 +29,8 @@ public final class CarrierAccountTest { private static TestUtils.VCR vcr; + private static MockedStatic requestMock = Mockito.mockStatic(Requestor.class); + /** * Set up the testing environment for this file. * @@ -38,6 +46,7 @@ public static void setup() throws EasyPostException { */ @AfterEach public void cleanup() { + requestMock.close(); if (testCarrierAccountId != null) { try { CarrierAccount carrierAccount = vcr.client.carrierAccount.retrieve(testCarrierAccountId); @@ -179,4 +188,42 @@ public void testTypes() throws EasyPostException { assertInstanceOf(List.class, types); assertTrue(types.stream().allMatch(type -> type != null)); } + + /** + * Test that the CarrierAccount fields are correctly deserialized from the API response. + * None of the demo carrier accounts used in the above tests have credentials or test credentials fields, so we need to use some mock data. + */ + @Test + public void testCarrierFieldsJsonDeserialization() { + String carrierAccountJson = "[{\"id\":\"ca_123\",\"object\":\"CarrierAccount\",\"fields\":{\"credentials\":{\"account_number\":{\"visibility\":\"visible\",\"label\":\"DHL Account Number\",\"value\":\"123456\"},\"country\":{\"visibility\":\"visible\",\"label\":\"Account Country Code (2 Letter)\",\"value\":\"US\"},\"site_id\":{\"visibility\":\"visible\",\"label\":\"Site ID (Optional)\",\"value\": null },\"password\":{\"visibility\":\"password\",\"label\":\"Password (Optional)\",\"value\":\"\"},\"is_reseller\":{\"visibility\":\"checkbox\",\"label\":\"Reseller Account? (check if yes)\",\"value\":null}}}}]"; + CarrierAccount[] carrierAccounts = Constants.Http.GSON.fromJson(carrierAccountJson, CarrierAccount[].class); + + CarrierAccount carrierAccount = carrierAccounts[0]; + assertEquals("ca_123", carrierAccount.getId()); + assertEquals("CarrierAccount", carrierAccount.getObject()); + assertEquals("DHL Account Number", carrierAccount.getFields().getCredentials().get("account_number").getLabel()); + } + + /** + * Test that the CarrierAccount fields are correctly serialized to the API request. + */ + @Test + public void testCarrierFieldsJsonSerialization() throws EasyPostException { + String carrierAccountJson = "[{\"id\":\"ca_123\",\"object\":\"CarrierAccount\",\"fields\":{\"credentials\":{\"account_number\":{\"visibility\":\"visible\",\"label\":\"DHL Account Number\",\"value\":\"123456\"},\"country\":{\"visibility\":\"visible\",\"label\":\"Account Country Code (2 Letter)\",\"value\":\"US\"},\"site_id\":{\"visibility\":\"visible\",\"label\":\"Site ID (Optional)\",\"value\": null },\"password\":{\"visibility\":\"password\",\"label\":\"Password (Optional)\",\"value\":\"\"},\"is_reseller\":{\"visibility\":\"checkbox\",\"label\":\"Reseller Account? (check if yes)\",\"value\":null}}}}]"; + CarrierAccount[] carrierAccounts = Constants.Http.GSON.fromJson(carrierAccountJson, CarrierAccount[].class); + CarrierAccount carrierAccount = carrierAccounts[0]; + + // Prepare a parameter set for creating a pickup, using the carrier account object + Shipment shipment = vcr.client.shipment.create(Fixtures.oneCallBuyShipment()); + Map pickupData = Fixtures.basicPickup(); + pickupData.put("shipment", shipment); + pickupData.put("carrier_accounts", new CarrierAccount[]{carrierAccount}); + + // Avoid making a real request to the API, interested in pre-request serialization, not interested in response + requestMock.when(() -> Requestor.request( + Requestor.RequestMethod.POST, "pickups", pickupData, Shipment.class, vcr.client)).thenReturn(new Pickup()); + + // This will throw an exception if the carrier account fields could not be serialized properly + assertDoesNotThrow(() -> vcr.client.pickup.create(pickupData)); + } } From 682f1c6dba1341434f19dc8db774384e28bf59fc Mon Sep 17 00:00:00 2001 From: Nate Harris Date: Fri, 12 Apr 2024 12:41:55 -0600 Subject: [PATCH 2/4] - Linting --- .../java/com/easypost/CarrierAccountTest.java | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/test/java/com/easypost/CarrierAccountTest.java b/src/test/java/com/easypost/CarrierAccountTest.java index e920a5e3e..0cd05c9a5 100644 --- a/src/test/java/com/easypost/CarrierAccountTest.java +++ b/src/test/java/com/easypost/CarrierAccountTest.java @@ -5,7 +5,6 @@ import com.easypost.http.Requestor; import com.easypost.model.CarrierAccount; import com.easypost.model.CarrierType; -import com.easypost.model.PaymentMethod; import com.easypost.model.Pickup; import com.easypost.model.Shipment; import com.google.common.collect.ImmutableMap; @@ -191,17 +190,25 @@ public void testTypes() throws EasyPostException { /** * Test that the CarrierAccount fields are correctly deserialized from the API response. - * None of the demo carrier accounts used in the above tests have credentials or test credentials fields, so we need to use some mock data. + * None of the demo carrier accounts used in the above tests have credentials or test credentials fields, + * so we need to use some mock data. */ @Test public void testCarrierFieldsJsonDeserialization() { - String carrierAccountJson = "[{\"id\":\"ca_123\",\"object\":\"CarrierAccount\",\"fields\":{\"credentials\":{\"account_number\":{\"visibility\":\"visible\",\"label\":\"DHL Account Number\",\"value\":\"123456\"},\"country\":{\"visibility\":\"visible\",\"label\":\"Account Country Code (2 Letter)\",\"value\":\"US\"},\"site_id\":{\"visibility\":\"visible\",\"label\":\"Site ID (Optional)\",\"value\": null },\"password\":{\"visibility\":\"password\",\"label\":\"Password (Optional)\",\"value\":\"\"},\"is_reseller\":{\"visibility\":\"checkbox\",\"label\":\"Reseller Account? (check if yes)\",\"value\":null}}}}]"; + String carrierAccountJson = "[{\"id\":\"ca_123\",\"object\":\"CarrierAccount\"," + + "\"fields\":{\"credentials\":{\"account_number\":{\"visibility\":\"visible\"," + + "\"label\":\"DHL Account Number\",\"value\":\"123456\"},\"country\":{\"visibility\":\"visible\"," + + "\"label\":\"Account Country Code (2 Letter)\",\"value\":\"US\"},\"site_id\":{\"visibility\":" + + "\"visible\",\"label\":\"Site ID (Optional)\",\"value\": null },\"password\":{\"visibility\":" + + "\"password\",\"label\":\"Password (Optional)\",\"value\":\"\"},\"is_reseller\":{\"visibility\":" + + "\"checkbox\",\"label\":\"Reseller Account? (check if yes)\",\"value\":null}}}}]"; CarrierAccount[] carrierAccounts = Constants.Http.GSON.fromJson(carrierAccountJson, CarrierAccount[].class); CarrierAccount carrierAccount = carrierAccounts[0]; assertEquals("ca_123", carrierAccount.getId()); assertEquals("CarrierAccount", carrierAccount.getObject()); - assertEquals("DHL Account Number", carrierAccount.getFields().getCredentials().get("account_number").getLabel()); + assertEquals("DHL Account Number", + carrierAccount.getFields().getCredentials().get("account_number").getLabel()); } /** @@ -209,7 +216,13 @@ public void testCarrierFieldsJsonDeserialization() { */ @Test public void testCarrierFieldsJsonSerialization() throws EasyPostException { - String carrierAccountJson = "[{\"id\":\"ca_123\",\"object\":\"CarrierAccount\",\"fields\":{\"credentials\":{\"account_number\":{\"visibility\":\"visible\",\"label\":\"DHL Account Number\",\"value\":\"123456\"},\"country\":{\"visibility\":\"visible\",\"label\":\"Account Country Code (2 Letter)\",\"value\":\"US\"},\"site_id\":{\"visibility\":\"visible\",\"label\":\"Site ID (Optional)\",\"value\": null },\"password\":{\"visibility\":\"password\",\"label\":\"Password (Optional)\",\"value\":\"\"},\"is_reseller\":{\"visibility\":\"checkbox\",\"label\":\"Reseller Account? (check if yes)\",\"value\":null}}}}]"; + String carrierAccountJson = "[{\"id\":\"ca_123\",\"object\":\"CarrierAccount\",\"fields\":{\"credentials\":" + + "{\"account_number\":{\"visibility\":\"visible\",\"label\":\"DHL Account Number\"," + + "\"value\":\"123456\"},\"country\":{\"visibility\":\"visible\",\"label\":" + + "\"Account Country Code (2 Letter)\",\"value\":\"US\"},\"site_id\":{\"visibility\":\"visible\"," + + "\"label\":\"Site ID (Optional)\",\"value\": null },\"password\":{\"visibility\":\"password\"," + + "\"label\":\"Password (Optional)\",\"value\":\"\"},\"is_reseller\":{\"visibility\":\"checkbox\"," + + "\"label\":\"Reseller Account? (check if yes)\",\"value\":null}}}}]"; CarrierAccount[] carrierAccounts = Constants.Http.GSON.fromJson(carrierAccountJson, CarrierAccount[].class); CarrierAccount carrierAccount = carrierAccounts[0]; @@ -217,11 +230,12 @@ public void testCarrierFieldsJsonSerialization() throws EasyPostException { Shipment shipment = vcr.client.shipment.create(Fixtures.oneCallBuyShipment()); Map pickupData = Fixtures.basicPickup(); pickupData.put("shipment", shipment); - pickupData.put("carrier_accounts", new CarrierAccount[]{carrierAccount}); + pickupData.put("carrier_accounts", new CarrierAccount[] { carrierAccount }); // Avoid making a real request to the API, interested in pre-request serialization, not interested in response - requestMock.when(() -> Requestor.request( - Requestor.RequestMethod.POST, "pickups", pickupData, Shipment.class, vcr.client)).thenReturn(new Pickup()); + requestMock.when(() -> Requestor.request(Requestor.RequestMethod.POST, "pickups", + pickupData, Shipment.class, + vcr.client)).thenReturn(new Pickup()); // This will throw an exception if the carrier account fields could not be serialized properly assertDoesNotThrow(() -> vcr.client.pickup.create(pickupData)); From 5625931dbfc07a3e534f0caccc4efce048233dcc Mon Sep 17 00:00:00 2001 From: Nate Harris Date: Fri, 12 Apr 2024 12:46:12 -0600 Subject: [PATCH 3/4] - Add missing logo property for CarrierAccount --- src/main/java/com/easypost/model/CarrierAccount.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/easypost/model/CarrierAccount.java b/src/main/java/com/easypost/model/CarrierAccount.java index 981808535..124b707eb 100644 --- a/src/main/java/com/easypost/model/CarrierAccount.java +++ b/src/main/java/com/easypost/model/CarrierAccount.java @@ -8,6 +8,7 @@ public final class CarrierAccount extends EasyPostResource { private String type; private Fields fields; private boolean clone; + private String logo; private String readable; private String description; private String reference; From ba3c5e6475a13f184db7020afdace1e45b54b680 Mon Sep 17 00:00:00 2001 From: Nate Harris Date: Fri, 12 Apr 2024 12:51:55 -0600 Subject: [PATCH 4/4] - Fix mocking for unit test --- src/test/java/com/easypost/CarrierAccountTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/easypost/CarrierAccountTest.java b/src/test/java/com/easypost/CarrierAccountTest.java index 0cd05c9a5..0afc53bef 100644 --- a/src/test/java/com/easypost/CarrierAccountTest.java +++ b/src/test/java/com/easypost/CarrierAccountTest.java @@ -45,7 +45,6 @@ public static void setup() throws EasyPostException { */ @AfterEach public void cleanup() { - requestMock.close(); if (testCarrierAccountId != null) { try { CarrierAccount carrierAccount = vcr.client.carrierAccount.retrieve(testCarrierAccountId); @@ -215,7 +214,7 @@ public void testCarrierFieldsJsonDeserialization() { * Test that the CarrierAccount fields are correctly serialized to the API request. */ @Test - public void testCarrierFieldsJsonSerialization() throws EasyPostException { + public void testCarrierFieldsJsonSerialization() { String carrierAccountJson = "[{\"id\":\"ca_123\",\"object\":\"CarrierAccount\",\"fields\":{\"credentials\":" + "{\"account_number\":{\"visibility\":\"visible\",\"label\":\"DHL Account Number\"," + "\"value\":\"123456\"},\"country\":{\"visibility\":\"visible\",\"label\":" + @@ -227,17 +226,18 @@ public void testCarrierFieldsJsonSerialization() throws EasyPostException { CarrierAccount carrierAccount = carrierAccounts[0]; // Prepare a parameter set for creating a pickup, using the carrier account object - Shipment shipment = vcr.client.shipment.create(Fixtures.oneCallBuyShipment()); Map pickupData = Fixtures.basicPickup(); - pickupData.put("shipment", shipment); + pickupData.put("shipment", new Shipment()); pickupData.put("carrier_accounts", new CarrierAccount[] { carrierAccount }); // Avoid making a real request to the API, interested in pre-request serialization, not interested in response - requestMock.when(() -> Requestor.request(Requestor.RequestMethod.POST, "pickups", - pickupData, Shipment.class, + requestMock.when(() -> Requestor.request(Requestor.RequestMethod.POST, "pickups", pickupData, Shipment.class, vcr.client)).thenReturn(new Pickup()); // This will throw an exception if the carrier account fields could not be serialized properly assertDoesNotThrow(() -> vcr.client.pickup.create(pickupData)); + + // Close mock + requestMock.close(); } }