From fae07168a660eda10e602ef2b9a5b535ee53df43 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Tue, 21 May 2024 15:24:46 -0700 Subject: [PATCH] When appAccountToken is null in ConsumptionRequest pass an empty string. Resolves https://github.com/apple/app-store-server-library-java/issues/99 --- .../model/AppAccountTokenNullSerializer.java | 15 ++++++ .../storekit/model/ConsumptionRequest.java | 2 + .../client/AppStoreServerAPIClientTest.java | 50 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 src/main/java/com/apple/itunes/storekit/model/AppAccountTokenNullSerializer.java diff --git a/src/main/java/com/apple/itunes/storekit/model/AppAccountTokenNullSerializer.java b/src/main/java/com/apple/itunes/storekit/model/AppAccountTokenNullSerializer.java new file mode 100644 index 00000000..d1b5f443 --- /dev/null +++ b/src/main/java/com/apple/itunes/storekit/model/AppAccountTokenNullSerializer.java @@ -0,0 +1,15 @@ +package com.apple.itunes.storekit.model; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.util.UUID; + +public class AppAccountTokenNullSerializer extends JsonSerializer { + @Override + public void serialize(UUID uuid, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeString(""); + } +} diff --git a/src/main/java/com/apple/itunes/storekit/model/ConsumptionRequest.java b/src/main/java/com/apple/itunes/storekit/model/ConsumptionRequest.java index 401ffb5a..f0308a3e 100644 --- a/src/main/java/com/apple/itunes/storekit/model/ConsumptionRequest.java +++ b/src/main/java/com/apple/itunes/storekit/model/ConsumptionRequest.java @@ -3,6 +3,7 @@ package com.apple.itunes.storekit.model; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.util.Objects; import java.util.UUID; @@ -36,6 +37,7 @@ public class ConsumptionRequest { @JsonProperty(SERIALIZED_NAME_DELIVERY_STATUS) private Integer deliveryStatus; @JsonProperty(SERIALIZED_NAME_APP_ACCOUNT_TOKEN) + @JsonSerialize(nullsUsing = AppAccountTokenNullSerializer.class) private UUID appAccountToken; @JsonProperty(SERIALIZED_NAME_ACCOUNT_TENURE) private Integer accountTenure; diff --git a/src/test/java/com/apple/itunes/storekit/client/AppStoreServerAPIClientTest.java b/src/test/java/com/apple/itunes/storekit/client/AppStoreServerAPIClientTest.java index 2ffe0e0e..74ff7470 100644 --- a/src/test/java/com/apple/itunes/storekit/client/AppStoreServerAPIClientTest.java +++ b/src/test/java/com/apple/itunes/storekit/client/AppStoreServerAPIClientTest.java @@ -450,6 +450,56 @@ public void testSendConsumptionData() throws APIException, IOException { client.sendConsumptionData("49571273", consumptionRequest); } + @Test + public void testSendConsumptionDataWithNullAppAccountToken() throws APIException, IOException { + AppStoreServerAPIClient client = getAppStoreServerAPIClient("", request -> { + Assertions.assertEquals("PUT", request.method()); + Assertions.assertEquals("/inApps/v1/transactions/consumption/49571273", request.url().encodedPath()); + RequestBody body = request.body(); + Assertions.assertNotNull(body); + Assertions.assertEquals(expectedMediaType, body.contentType()); + Buffer buffer = new Buffer(); + try { + body.writeTo(buffer); + } catch (IOException e) { + throw new RuntimeException(e); + } + Map root; + try { + root = new ObjectMapper().readValue(buffer.readUtf8(), Map.class); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + Assertions.assertTrue((Boolean) root.get("customerConsented")); + Assertions.assertEquals(1, ((Number) root.get("consumptionStatus")).intValue()); + Assertions.assertEquals(2, ((Number) root.get("platform")).intValue()); + Assertions.assertFalse((Boolean) root.get("sampleContentProvided")); + Assertions.assertEquals(3, ((Number) root.get("deliveryStatus")).intValue()); + Assertions.assertEquals("", root.get("appAccountToken")); + Assertions.assertEquals(4, ((Number) root.get("accountTenure")).intValue()); + Assertions.assertEquals(5, ((Number) root.get("playTime")).intValue()); + Assertions.assertEquals(6, ((Number) root.get("lifetimeDollarsRefunded")).intValue()); + Assertions.assertEquals(7, ((Number) root.get("lifetimeDollarsPurchased")).intValue()); + Assertions.assertEquals(4, ((Number) root.get("userStatus")).intValue()); + Assertions.assertEquals(3, ((Number) root.get("refundPreference")).intValue()); + }); + + ConsumptionRequest consumptionRequest = new ConsumptionRequest() + .customerConsented(true) + .consumptionStatus(ConsumptionStatus.NOT_CONSUMED) + .platform(Platform.NON_APPLE) + .sampleContentProvided(false) + .deliveryStatus(DeliveryStatus.DID_NOT_DELIVER_DUE_TO_SERVER_OUTAGE) + .accountTenure(AccountTenure.THIRTY_DAYS_TO_NINETY_DAYS) + .playTime(PlayTime.ONE_DAY_TO_FOUR_DAYS) + .lifetimeDollarsRefunded(LifetimeDollarsRefunded.ONE_THOUSAND_DOLLARS_TO_ONE_THOUSAND_NINE_HUNDRED_NINETY_NINE_DOLLARS_AND_NINETY_NINE_CENTS) + .lifetimeDollarsPurchased(LifetimeDollarsPurchased.TWO_THOUSAND_DOLLARS_OR_GREATER) + .userStatus(UserStatus.LIMITED_ACCESS) + .refundPreference(RefundPreference.NO_PREFERENCE); + + client.sendConsumptionData("49571273", consumptionRequest); + } + @Test public void testHeaders() throws APIException, IOException { AppStoreServerAPIClient client = getClientWithBody("models/transactionInfoResponse.json", request -> {