From 4dd93fffe9237c32c55bd8901ae54d5c81e0a81e Mon Sep 17 00:00:00 2001 From: hicham Date: Mon, 14 Feb 2022 16:52:46 +0100 Subject: [PATCH 1/3] Add a type adapter to handle null string serialization --- .../fluxc/utils/NullStringJsonAdapter.kt | 32 +++++++++++ .../fluxc/utils/NullStringJsonAdapterTests.kt | 57 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/utils/NullStringJsonAdapter.kt create mode 100644 plugins/woocommerce/src/test/java/org/wordpress/android/fluxc/utils/NullStringJsonAdapterTests.kt diff --git a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/utils/NullStringJsonAdapter.kt b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/utils/NullStringJsonAdapter.kt new file mode 100644 index 0000000000..dafa98b94b --- /dev/null +++ b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/utils/NullStringJsonAdapter.kt @@ -0,0 +1,32 @@ +package org.wordpress.android.fluxc.utils + +import com.google.gson.TypeAdapter +import com.google.gson.stream.JsonReader +import com.google.gson.stream.JsonToken.NULL +import com.google.gson.stream.JsonToken.STRING +import com.google.gson.stream.JsonWriter +import com.google.gson.stream.MalformedJsonException + +class NullStringJsonAdapter : TypeAdapter() { + override fun write(out: JsonWriter, value: String?) { + val defaultSerializeNullValue = out.serializeNulls + out.serializeNulls = true + if (value == null) { + out.nullValue() + } else { + out.value(value) + } + out.serializeNulls = defaultSerializeNullValue + } + + override fun read(input: JsonReader): String? { + return when (val token = input.peek()) { + STRING -> input.nextString() + NULL -> { + input.nextNull() + null + } + else -> throw MalformedJsonException("Unexpected token: $token") + } + } +} diff --git a/plugins/woocommerce/src/test/java/org/wordpress/android/fluxc/utils/NullStringJsonAdapterTests.kt b/plugins/woocommerce/src/test/java/org/wordpress/android/fluxc/utils/NullStringJsonAdapterTests.kt new file mode 100644 index 0000000000..e16a7f636a --- /dev/null +++ b/plugins/woocommerce/src/test/java/org/wordpress/android/fluxc/utils/NullStringJsonAdapterTests.kt @@ -0,0 +1,57 @@ +package org.wordpress.android.fluxc.utils + +import com.google.gson.Gson +import com.google.gson.annotations.JsonAdapter +import com.google.gson.annotations.SerializedName +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test + +class NullStringJsonAdapterTests { + data class Example( + @JsonAdapter(NullStringJsonAdapter::class, nullSafe = false) + @SerializedName("an_id") + val id: String? + ) + + private val gson = Gson() + + @Test + fun `when passing null in json, then it should be deserialized to null value`() { + val json = """{ + "an_id": null + }""" + + val example = gson.fromJson(json, Example::class.java) + + assertThat(example.id).isNull() + } + + @Test + fun `when serializing a null value, then it should be exposed to the json`() { + val example = Example(null) + + val json = gson.toJson(example) + + assertThat(json).contains(""""an_id":null""") + } + + @Test + fun `when passing non-null value in json, then it should be deserialized to the correct value`() { + val json = """{ + "an_id": "some_id" + }""" + + val example = gson.fromJson(json, Example::class.java) + + assertThat(example.id).isEqualTo("some_id") + } + + @Test + fun `when serializing a non-null value, then it should be correctly serialized`() { + val example = Example("some_id") + + val json = gson.toJson(example) + + assertThat(json).contains(""""an_id":"some_id"""") + } +} From 7a7e5f07d88c87b83cabe49bf5cc78a0f60e6228 Mon Sep 17 00:00:00 2001 From: hicham Date: Mon, 14 Feb 2022 16:54:38 +0100 Subject: [PATCH 2/3] Make sure the method_id null values are serialized --- .../org/wordpress/android/fluxc/model/order/ShippingLine.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/model/order/ShippingLine.kt b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/model/order/ShippingLine.kt index 2343040e52..260b79b36e 100644 --- a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/model/order/ShippingLine.kt +++ b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/model/order/ShippingLine.kt @@ -1,6 +1,8 @@ package org.wordpress.android.fluxc.model.order +import com.google.gson.annotations.JsonAdapter import com.google.gson.annotations.SerializedName +import org.wordpress.android.fluxc.utils.NullStringJsonAdapter data class ShippingLine( val id: Long? = null, @@ -8,6 +10,7 @@ data class ShippingLine( @SerializedName("total_tax") val totalTax: String? = null, @SerializedName("method_id") + @JsonAdapter(NullStringJsonAdapter::class, nullSafe = false) val methodId: String? = null, @SerializedName("method_title") val methodTitle: String? = null From 9a5f5b4aec420f545ad3867deedb1234fc9318c1 Mon Sep 17 00:00:00 2001 From: hicham Date: Mon, 14 Feb 2022 16:54:55 +0100 Subject: [PATCH 3/3] Make sure the name null values are serialized --- .../kotlin/org/wordpress/android/fluxc/model/order/FeeLine.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/model/order/FeeLine.kt b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/model/order/FeeLine.kt index a6bcf53cc5..4806ee3232 100644 --- a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/model/order/FeeLine.kt +++ b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/model/order/FeeLine.kt @@ -1,6 +1,8 @@ package org.wordpress.android.fluxc.model.order +import com.google.gson.annotations.JsonAdapter import com.google.gson.annotations.SerializedName +import org.wordpress.android.fluxc.utils.NullStringJsonAdapter /** * Represents a fee line. @@ -10,6 +12,7 @@ class FeeLine { var id: Long? = null @SerializedName("name") + @JsonAdapter(NullStringJsonAdapter::class, nullSafe = false) var name: String? = null @SerializedName("total")