From cebfe75bd81b335ee1729268b4ff3a2604b487b3 Mon Sep 17 00:00:00 2001 From: Hafiz Rahman Date: Thu, 12 Dec 2024 13:34:38 +0700 Subject: [PATCH 1/8] Add /orders/batch endpoint --- fluxc-processor/src/main/resources/wc-wp-api-endpoints.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/fluxc-processor/src/main/resources/wc-wp-api-endpoints.txt b/fluxc-processor/src/main/resources/wc-wp-api-endpoints.txt index e155c45b88..cbd1823df5 100644 --- a/fluxc-processor/src/main/resources/wc-wp-api-endpoints.txt +++ b/fluxc-processor/src/main/resources/wc-wp-api-endpoints.txt @@ -6,6 +6,7 @@ /orders//shipment-trackings/providers/ /orders//receipt/ /orders//actions/send_order_details +/orders/batch /products// /products//variations/ From 44bc77a3b35c640418dff9172e7ac2cb0154b4d4 Mon Sep 17 00:00:00 2001 From: Hafiz Rahman Date: Thu, 12 Dec 2024 15:32:54 +0700 Subject: [PATCH 2/8] Add sample response for PUT wc/v3/orders/batch with both success and error cases --- .../src/test/resources/wc/orders-batch.json | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 example/src/test/resources/wc/orders-batch.json diff --git a/example/src/test/resources/wc/orders-batch.json b/example/src/test/resources/wc/orders-batch.json new file mode 100644 index 0000000000..e4a2f1930f --- /dev/null +++ b/example/src/test/resources/wc/orders-batch.json @@ -0,0 +1,160 @@ +{ + "update": [ + { + "id": 1032, + "parent_id": 0, + "status": "completed", + "currency": "USD", + "version": "9.4.3", + "prices_include_tax": false, + "date_created": "2024-12-04T11:21:17", + "date_modified": "2024-12-04T11:23:19", + "discount_total": "0.00", + "discount_tax": "0.00", + "shipping_total": "3.00", + "shipping_tax": "0.00", + "cart_tax": "0.00", + "total": "224.00", + "total_tax": "0.00", + "customer_id": 0, + "order_key": "wc_order_XXXXXXXXXXXX", + "billing": { + "first_name": "", + "last_name": "", + "company": "", + "address_1": "", + "address_2": "", + "city": "", + "state": "", + "postcode": "", + "country": "", + "email": "", + "phone": "" + }, + "shipping": { + "first_name": "", + "last_name": "", + "company": "", + "address_1": "", + "address_2": "", + "city": "", + "state": "", + "postcode": "", + "country": "", + "phone": "" + }, + "payment_method": "", + "payment_method_title": "", + "transaction_id": "", + "customer_ip_address": "", + "customer_user_agent": "", + "created_via": "rest-api", + "customer_note": "Asdasd", + "date_completed": "2024-12-04T11:23:19", + "date_paid": "2024-12-04T11:23:19", + "cart_hash": "", + "number": "1032", + "meta_data": [ + { + "id": 18608, + "key": "_wc_order_attribution_source_type", + "value": "mobile_app" + } + ], + "line_items": [ + { + "id": 162, + "name": "Album", + "product_id": 71, + "variation_id": 0, + "quantity": 1, + "tax_class": "", + "subtotal": "216.00", + "subtotal_tax": "0.00", + "total": "216.00", + "total_tax": "0.00", + "taxes": [], + "meta_data": [], + "sku": "woo-album", + "price": 216, + "image": { + "id": "100", + "src": "https://example.com/images/album-1.jpg" + }, + "parent_name": null, + "bundled_by": "", + "bundled_item_title": "", + "bundled_items": [] + } + ], + "tax_lines": [], + "shipping_lines": [ + { + "id": 166, + "method_title": "Reg ship", + "method_id": "flat_rate", + "instance_id": "", + "total": "3.00", + "total_tax": "0.00", + "taxes": [], + "meta_data": [] + } + ], + "fee_lines": [ + { + "id": 165, + "name": "Just for you", + "tax_class": "", + "tax_status": "none", + "amount": "", + "total": "5.00", + "total_tax": "0.00", + "taxes": [], + "meta_data": [] + } + ], + "coupon_lines": [], + "refunds": [], + "payment_url": "https://example.com/checkout/order-pay/1032/", + "is_editable": false, + "needs_payment": false, + "needs_processing": true, + "date_created_gmt": "2024-12-04T04:21:17", + "date_modified_gmt": "2024-12-04T04:23:19", + "date_completed_gmt": "2024-12-04T04:23:19", + "date_paid_gmt": "2024-12-04T04:23:19", + "currency_symbol": "$", + "_links": { + "self": [ + { + "href": "https://example.com/wp-json/wc/v3/orders/1032", + "targetHints": { + "allow": [ + "GET", + "POST", + "PUT", + "PATCH", + "DELETE" + ] + } + } + ], + "collection": [ + { + "href": "https://example.com/wp-json/wc/v3/orders" + } + ] + } + }, + { + "id": "525", + "error": { + "code": "woocommerce_rest_shop_order_invalid_id", + "message": "Id tidak valid.", + "data": { + "status": 400 + } + } + } + ] +} \ No newline at end of file From 7b8793e22936377c7fd8591de884133b6ec487e3 Mon Sep 17 00:00:00 2001 From: Hafiz Rahman Date: Thu, 12 Dec 2024 16:06:10 +0700 Subject: [PATCH 3/8] Add BatchOrderApiResponse class --- .../wpcom/wc/order/BatchOrderApiResponse.kt | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt diff --git a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt new file mode 100644 index 0000000000..1e9cee4f80 --- /dev/null +++ b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt @@ -0,0 +1,53 @@ +package org.wordpress.android.fluxc.network.rest.wpcom.wc.order + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonDeserializer +import com.google.gson.JsonElement +import com.google.gson.annotations.SerializedName +import java.lang.reflect.Type + +data class BatchOrderApiResponse( + @SerializedName("update") val update: List +) { + sealed class OrderResponse { + data class Success( + val order: OrderDto + ) : OrderResponse() + + data class Error( + val id: Long, + val error: ErrorResponse + ) : OrderResponse() + } + + data class ErrorResponse( + val code: String, + val message: String, + val data: ErrorData + ) + + data class ErrorData( + val status: Int + ) + + class OrderResponseDeserializer : JsonDeserializer { + override fun deserialize( + json: JsonElement, + typeOfT: Type, + context: JsonDeserializationContext + ): OrderResponse { + val jsonObject = json.asJsonObject + + return if (jsonObject.has("error")) { + OrderResponse.Error( + id = jsonObject.get("id").asLong, + error = context.deserialize(jsonObject.get("error"), ErrorResponse::class.java) + ) + } else { + OrderResponse.Success( + context.deserialize(jsonObject, OrderDto::class.java) + ) + } + } + } +} From 0a0d3ebed6418d18848c81828d2d799c83e3b055 Mon Sep 17 00:00:00 2001 From: Hafiz Rahman Date: Thu, 12 Dec 2024 16:06:47 +0700 Subject: [PATCH 4/8] Add unit test for batch order response's deserializer. --- .../android/fluxc/wc/order/OrderEntityTest.kt | 29 +++++++++++++++++++ .../src/test/resources/wc/orders-batch.json | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt b/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt index 16019ed5ef..9993901a28 100644 --- a/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt +++ b/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt @@ -1,10 +1,12 @@ package org.wordpress.android.fluxc.wc.order import com.google.gson.Gson +import com.google.gson.GsonBuilder import com.google.gson.reflect.TypeToken import org.junit.Test import org.wordpress.android.fluxc.UnitTestUtils import org.wordpress.android.fluxc.model.order.ShippingLine +import org.wordpress.android.fluxc.network.rest.wpcom.wc.order.BatchOrderApiResponse import kotlin.test.assertEquals import kotlin.test.assertNull import kotlin.test.assertTrue @@ -143,4 +145,31 @@ class OrderEntityTest { assertEquals("Flat Rate Shipping", shippingLinesList[0].methodTitle) assertEquals("Local Pickup Shipping", shippingLinesList[1].methodTitle) } + + @Test + fun testDeserializeBatchOrderResponse() { + val testGson = GsonBuilder() + .registerTypeAdapter( + BatchOrderApiResponse.OrderResponse::class.java, + BatchOrderApiResponse.OrderResponseDeserializer()) + .create() + + val batchOrderJson = UnitTestUtils.getStringFromResourceFile( + this.javaClass, "wc/orders-batch.json" + ) + + val response = testGson.fromJson(batchOrderJson, BatchOrderApiResponse::class.java) + val orders = response.update + + assertEquals(2, orders.size) + + val firstOrder = orders[0] as BatchOrderApiResponse.OrderResponse.Success + assertEquals(1032L, firstOrder.order.id) + assertEquals("224.00", firstOrder.order.total) + + val secondOrder = orders[1] as BatchOrderApiResponse.OrderResponse.Error + assertEquals(525L, secondOrder.id) + assertEquals("woocommerce_rest_shop_order_invalid_id", secondOrder.error.code) + assertEquals(400, secondOrder.error.data.status) + } } diff --git a/example/src/test/resources/wc/orders-batch.json b/example/src/test/resources/wc/orders-batch.json index e4a2f1930f..614dac826d 100644 --- a/example/src/test/resources/wc/orders-batch.json +++ b/example/src/test/resources/wc/orders-batch.json @@ -150,7 +150,7 @@ "id": "525", "error": { "code": "woocommerce_rest_shop_order_invalid_id", - "message": "Id tidak valid.", + "message": "Invalid ID.", "data": { "status": 400 } From 3c423f4b9646625298b72fbc52b981b47a7484c6 Mon Sep 17 00:00:00 2001 From: Hafiz Rahman Date: Thu, 12 Dec 2024 18:37:42 +0700 Subject: [PATCH 5/8] Remove unneeded Serialized name and add subclass to Response --- .../network/rest/wpcom/wc/order/BatchOrderApiResponse.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt index 1e9cee4f80..599a727c76 100644 --- a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt +++ b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt @@ -3,12 +3,12 @@ package org.wordpress.android.fluxc.network.rest.wpcom.wc.order import com.google.gson.JsonDeserializationContext import com.google.gson.JsonDeserializer import com.google.gson.JsonElement -import com.google.gson.annotations.SerializedName import java.lang.reflect.Type +import org.wordpress.android.fluxc.network.Response data class BatchOrderApiResponse( - @SerializedName("update") val update: List -) { + val update: List +) : Response { sealed class OrderResponse { data class Success( val order: OrderDto From 254cf5cc46aaa810fad33c172580151105ffdde3 Mon Sep 17 00:00:00 2001 From: Hafiz Rahman Date: Fri, 13 Dec 2024 08:42:45 +0700 Subject: [PATCH 6/8] Directly register TypeAdapter with annotation. --- .../org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt | 3 --- .../network/rest/wpcom/wc/order/BatchOrderApiResponse.kt | 4 +++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt b/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt index 9993901a28..4cb3b6f763 100644 --- a/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt +++ b/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt @@ -149,9 +149,6 @@ class OrderEntityTest { @Test fun testDeserializeBatchOrderResponse() { val testGson = GsonBuilder() - .registerTypeAdapter( - BatchOrderApiResponse.OrderResponse::class.java, - BatchOrderApiResponse.OrderResponseDeserializer()) .create() val batchOrderJson = UnitTestUtils.getStringFromResourceFile( diff --git a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt index 599a727c76..d2c942a799 100644 --- a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt +++ b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt @@ -3,12 +3,14 @@ package org.wordpress.android.fluxc.network.rest.wpcom.wc.order import com.google.gson.JsonDeserializationContext import com.google.gson.JsonDeserializer import com.google.gson.JsonElement +import com.google.gson.annotations.JsonAdapter import java.lang.reflect.Type import org.wordpress.android.fluxc.network.Response data class BatchOrderApiResponse( val update: List ) : Response { + @JsonAdapter(OrderResponseDeserializer::class) sealed class OrderResponse { data class Success( val order: OrderDto @@ -30,7 +32,7 @@ data class BatchOrderApiResponse( val status: Int ) - class OrderResponseDeserializer : JsonDeserializer { + private class OrderResponseDeserializer : JsonDeserializer { override fun deserialize( json: JsonElement, typeOfT: Type, From 6e2cdef91ec341072f91c5568125115ba42ef6e3 Mon Sep 17 00:00:00 2001 From: Hafiz Rahman Date: Fri, 13 Dec 2024 09:11:43 +0700 Subject: [PATCH 7/8] Move unit test to its own file with the same package location as BatchOrderApiResponse --- .../wc/order/BatchOrderApiResponseTest.kt | 32 +++++++++++++++++++ .../android/fluxc/wc/order/OrderEntityTest.kt | 24 -------------- 2 files changed, 32 insertions(+), 24 deletions(-) create mode 100644 example/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponseTest.kt diff --git a/example/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponseTest.kt b/example/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponseTest.kt new file mode 100644 index 0000000000..c5166c1234 --- /dev/null +++ b/example/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponseTest.kt @@ -0,0 +1,32 @@ +package org.wordpress.android.fluxc.network.rest.wpcom.wc.order + +import com.google.gson.GsonBuilder +import org.junit.Test +import org.wordpress.android.fluxc.UnitTestUtils +import kotlin.test.assertEquals + +class BatchOrderApiResponseTest { + @Test + fun testDeserializeBatchOrderResponse() { + val testGson = GsonBuilder() + .create() + + val batchOrderJson = UnitTestUtils.getStringFromResourceFile( + this.javaClass, "wc/orders-batch.json" + ) + + val response = testGson.fromJson(batchOrderJson, BatchOrderApiResponse::class.java) + val orders = response.update + + assertEquals(2, orders.size) + + val firstOrder = orders[0] as BatchOrderApiResponse.OrderResponse.Success + assertEquals(1032L, firstOrder.order.id) + assertEquals("224.00", firstOrder.order.total) + + val secondOrder = orders[1] as BatchOrderApiResponse.OrderResponse.Error + assertEquals(525L, secondOrder.id) + assertEquals("woocommerce_rest_shop_order_invalid_id", secondOrder.error.code) + assertEquals(400, secondOrder.error.data.status) + } +} diff --git a/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt b/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt index 4cb3b6f763..aa861edb9f 100644 --- a/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt +++ b/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt @@ -145,28 +145,4 @@ class OrderEntityTest { assertEquals("Flat Rate Shipping", shippingLinesList[0].methodTitle) assertEquals("Local Pickup Shipping", shippingLinesList[1].methodTitle) } - - @Test - fun testDeserializeBatchOrderResponse() { - val testGson = GsonBuilder() - .create() - - val batchOrderJson = UnitTestUtils.getStringFromResourceFile( - this.javaClass, "wc/orders-batch.json" - ) - - val response = testGson.fromJson(batchOrderJson, BatchOrderApiResponse::class.java) - val orders = response.update - - assertEquals(2, orders.size) - - val firstOrder = orders[0] as BatchOrderApiResponse.OrderResponse.Success - assertEquals(1032L, firstOrder.order.id) - assertEquals("224.00", firstOrder.order.total) - - val secondOrder = orders[1] as BatchOrderApiResponse.OrderResponse.Error - assertEquals(525L, secondOrder.id) - assertEquals("woocommerce_rest_shop_order_invalid_id", secondOrder.error.code) - assertEquals(400, secondOrder.error.data.status) - } } From 6a3a7290dfa9f06c607a0677aac1133026ef048c Mon Sep 17 00:00:00 2001 From: Hafiz Rahman Date: Fri, 13 Dec 2024 09:17:36 +0700 Subject: [PATCH 8/8] Remove unused import --- .../org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt b/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt index aa861edb9f..16019ed5ef 100644 --- a/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt +++ b/example/src/test/java/org/wordpress/android/fluxc/wc/order/OrderEntityTest.kt @@ -1,12 +1,10 @@ package org.wordpress.android.fluxc.wc.order import com.google.gson.Gson -import com.google.gson.GsonBuilder import com.google.gson.reflect.TypeToken import org.junit.Test import org.wordpress.android.fluxc.UnitTestUtils import org.wordpress.android.fluxc.model.order.ShippingLine -import org.wordpress.android.fluxc.network.rest.wpcom.wc.order.BatchOrderApiResponse import kotlin.test.assertEquals import kotlin.test.assertNull import kotlin.test.assertTrue