-
Notifications
You must be signed in to change notification settings - Fork 0
[Detail Bug] ETA API deserialization drops travel times and transport type due to JSON name and enum case mismatches #64
Copy link
Copy link
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Detail Bug Report
Summary
- Context:
EtaEstimateis a domain model record used to represent travel time and distance estimates returned by the Apple Maps Server API. - Bug: The field names
expectedTravelTimeSecondsandstaticTravelTimeSecondsin theEtaEstimaterecord do not match the corresponding field namesexpectedTravelTimeandstaticTravelTimereturned by the Apple Maps Server API. Additionally, theTransportTypeenum fails to deserialize when the API returns uppercase values (e.g., "AUTOMOBILE") because it is configured to usetoString(), which returns mixed case (e.g., "Automobile"). - Actual vs. expected: Jackson fails to populate the travel time fields during deserialization, resulting in
Optional.empty()for these values even when the API provides them. For the transport type, it also results inOptional.empty()(or null) due to the case mismatch. - Impact: Applications using this SDK to fetch ETAs will receive empty travel time estimates and missing transport types, making the ETA functionality effectively broken and unreliable.
Code with Bug
// src/main/java/com/williamcallahan/applemaps/domain/model/EtaEstimate.java
public record EtaEstimate(
Optional<Location> destination,
Optional<Long> distanceMeters,
Optional<Long> expectedTravelTimeSeconds, // <-- BUG 🔴 Should be expectedTravelTime to match API
Optional<Long> staticTravelTimeSeconds, // <-- BUG 🔴 Should be staticTravelTime to match API
Optional<TransportType> transportType
) {// src/main/java/com/williamcallahan/applemaps/adapters/jackson/AppleMapsObjectMapperFactory.java
.enable(EnumFeature.READ_ENUMS_USING_TO_STRING) // <-- BUG 🔴 Causes mismatch if API returns "AUTOMOBILE"// src/main/java/com/williamcallahan/applemaps/domain/model/TransportType.java
public enum TransportType {
AUTOMOBILE("Automobile"), // toString() returns "Automobile"
// ...
@Override
public String toString() {
return apiValue;
}
}Explanation
- Jackson maps record component names to JSON properties by default. Because the API returns
expectedTravelTime/staticTravelTimebut the model expectsexpectedTravelTimeSeconds/staticTravelTimeSeconds, those values are not bound and remainOptional.empty(). - The object mapper is configured with
READ_ENUMS_USING_TO_STRING, so Jackson expects enum JSON values to matchTransportType.toString()(e.g., "Automobile"). The API returns uppercase values (e.g., "AUTOMOBILE"), so deserialization fails to match and the field is missing/empty.
Failing Test
// src/test/java/com/williamcallahan/applemaps/domain/model/EtaEstimateDeserializationTest.java
@Test
void deserializesFromApiJson() throws Exception {
ObjectMapper objectMapper = AppleMapsObjectMapperFactory.create();
// This JSON follows the actual Apple Maps Server API for ETAs
String json = """
{
"destination": { "lat": 37.3346, "lng": -122.0090 },
"distanceMeters": 5000,
"expectedTravelTime": 600,
"staticTravelTime": 550,
"transportType": "AUTOMOBILE"
}
""";
EtaEstimate estimate = objectMapper.readValue(json, EtaEstimate.class);
// This assertion FAILED
assertTrue(estimate.expectedTravelTimeSeconds().isPresent(), "expectedTravelTimeSeconds should be present");
}Test output:
EtaEstimateDeserializationTest > deserializesFromApiJson() FAILED org.opentest4j.AssertionFailedError
Recommended Fix
Add explicit JSON mapping so the model matches the API keys (or rename the record components). For TransportType, either stop using READ_ENUMS_USING_TO_STRING or ensure toString() matches the API’s uppercase values.
public record EtaEstimate(
Optional<Location> destination,
Optional<Long> distanceMeters,
@JsonAlias("expectedTravelTime") Optional<Long> expectedTravelTimeSeconds, // <-- FIX 🟢
@JsonAlias("staticTravelTime") Optional<Long> staticTravelTimeSeconds, // <-- FIX 🟢
Optional<TransportType> transportType
)History
This bug was introduced in commit 33eca2a. This commit introduced the core domain models, but used descriptive field names (like expectedTravelTimeSeconds) and mixed-case enum strings that do not match the literal JSON keys and values returned by the Apple Maps Server API.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working