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/resources/wc/orders-batch.json b/example/src/test/resources/wc/orders-batch.json new file mode 100644 index 0000000000..614dac826d --- /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": "Invalid ID.", + "data": { + "status": 400 + } + } + } + ] +} \ No newline at end of file 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/ 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..d2c942a799 --- /dev/null +++ b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/order/BatchOrderApiResponse.kt @@ -0,0 +1,55 @@ +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 + ) : 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 + ) + + private 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) + ) + } + } + } +}