Skip to content
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

[fix] Invalid Fields structure #312

Merged
merged 4 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/easypost/model/CarrierAccount.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/easypost/model/Field.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

@Getter
public class Field extends EasyPostResource {
private String key;
private String visibility;
private String label;
private String value;
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/easypost/model/Fields.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

import lombok.Getter;

import java.util.Map;

@Getter
public class Fields extends EasyPostResource {
private Map<String, Field> credentials;
private Map<String, Field> testCredentials;
private boolean autoLink;
private boolean customWorkflow;
}
9 changes: 0 additions & 9 deletions src/test/java/com/easypost/BillingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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_" +
nwithan8 marked this conversation as resolved.
Show resolved Hide resolved
"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<Requestor> requestMock = Mockito.mockStatic(Requestor.class);

/**
Expand Down
61 changes: 61 additions & 0 deletions src/test/java/com/easypost/CarrierAccountTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@

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.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;
Expand All @@ -23,6 +28,8 @@ public final class CarrierAccountTest {

private static TestUtils.VCR vcr;

private static MockedStatic<Requestor> requestMock = Mockito.mockStatic(Requestor.class);

/**
* Set up the testing environment for this file.
*
Expand Down Expand Up @@ -179,4 +186,58 @@ 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() {
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
Map<String, Object> pickupData = Fixtures.basicPickup();
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,
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();
}
}
Loading