diff --git a/platforms/android/lib/api/lib.api b/platforms/android/lib/api/lib.api index b8bf226b9..024f6cf54 100644 --- a/platforms/android/lib/api/lib.api +++ b/platforms/android/lib/api/lib.api @@ -76,6 +76,7 @@ public final class com/shopify/checkoutkit/CheckoutProtocol { public static final field SPEC_VERSION Ljava/lang/String; public final fun getComplete ()Lcom/shopify/ucp/embedded/checkout/NotificationDescriptor; public final fun getError ()Lcom/shopify/ucp/embedded/checkout/NotificationDescriptor; + public final fun getFulfillmentChange ()Lcom/shopify/ucp/embedded/checkout/NotificationDescriptor; public final fun getLineItemsChange ()Lcom/shopify/ucp/embedded/checkout/NotificationDescriptor; public final fun getMessagesChange ()Lcom/shopify/ucp/embedded/checkout/NotificationDescriptor; public final fun getStart ()Lcom/shopify/ucp/embedded/checkout/NotificationDescriptor; diff --git a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutProtocol.kt b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutProtocol.kt index cfa386a63..716458db6 100644 --- a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutProtocol.kt +++ b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutProtocol.kt @@ -32,6 +32,7 @@ public object CheckoutProtocol { public val messagesChange: NotificationDescriptor = EmbeddedCheckoutProtocol.messagesChange public val lineItemsChange: NotificationDescriptor = EmbeddedCheckoutProtocol.lineItemsChange public val totalsChange: NotificationDescriptor = EmbeddedCheckoutProtocol.totalsChange + public val fulfillmentChange: NotificationDescriptor = EmbeddedCheckoutProtocol.fulfillmentChange public val error: NotificationDescriptor = EmbeddedCheckoutProtocol.error public val windowOpen: DelegationDescriptor = EmbeddedCheckoutProtocol.windowOpen.map( @@ -53,6 +54,7 @@ public object CheckoutProtocol { lineItemsChange.method, messagesChange.method, totalsChange.method, + fulfillmentChange.method, windowOpen.method, ) @@ -75,6 +77,7 @@ public object CheckoutProtocol { messagesChange, lineItemsChange, totalsChange, + fulfillmentChange, error, ) diff --git a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutProtocolTest.kt b/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutProtocolTest.kt index dd9a3f1bb..a9cd32f91 100644 --- a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutProtocolTest.kt +++ b/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutProtocolTest.kt @@ -50,6 +50,11 @@ class CheckoutProtocolTest { assertThat(CheckoutProtocol.lineItemsChange.method).isEqualTo("ec.line_items.change") } + @Test + fun `fulfillmentChange descriptor has correct method`() { + assertThat(CheckoutProtocol.fulfillmentChange.method).isEqualTo("ec.fulfillment.change") + } + @Test fun `error descriptor has correct method`() { assertThat(CheckoutProtocol.error.method).isEqualTo("ec.error") @@ -75,6 +80,7 @@ class CheckoutProtocolTest { CheckoutProtocol.lineItemsChange.method, CheckoutProtocol.messagesChange.method, CheckoutProtocol.totalsChange.method, + CheckoutProtocol.fulfillmentChange.method, CheckoutProtocol.windowOpen.method, ) } @@ -150,6 +156,18 @@ class CheckoutProtocolTest { assertThat(received).hasSize(1) } + @Test + fun `process dispatches ec fulfillment change to registered handler`() { + val received = mutableListOf() + val client = CheckoutProtocol.Client() + .on(CheckoutProtocol.fulfillmentChange) { checkout -> received.add(checkout) } + + client.process(checkoutMessage(method = CheckoutProtocol.fulfillmentChange.method)) + shadowOf(Looper.getMainLooper()).runToEndOfTasks() + + assertThat(received).hasSize(1) + } + @Test fun `process does not dispatch to unregistered method`() { val received = mutableListOf() @@ -506,10 +524,22 @@ class CheckoutProtocolTest { // region helpers private fun ecStartMessage(currency: String = "USD"): String = - """{"jsonrpc":"2.0","method":"ec.start","params":{"checkout":${checkoutJson(currency = currency)}}}""" + checkoutMessage(method = "ec.start", currency = currency) private fun ecCompleteMessage(): String = - """{"jsonrpc":"2.0","method":"ec.complete","params":{"checkout":${checkoutJson(status = "completed")}}}""" + checkoutMessage(method = "ec.complete", status = "completed") + + private fun checkoutMessage( + method: String, + currency: String = "USD", + status: String = "incomplete", + ): String { + val checkout = checkoutJson( + currency = currency, + status = status, + ) + return """{"jsonrpc":"2.0","method":"$method","params":{"checkout":$checkout}}""" + } private fun windowOpenMessage(id: String, url: String = "https://example.com"): String = """{"jsonrpc":"2.0","method":"ec.window.open_request","id":$id,"params":{"url":"$url"}}""" diff --git a/platforms/android/samples/CheckoutKitAndroidDemo/app/src/main/java/com/shopify/checkout_kit_android_demo/cart/CartViewModel.kt b/platforms/android/samples/CheckoutKitAndroidDemo/app/src/main/java/com/shopify/checkout_kit_android_demo/cart/CartViewModel.kt index 97f818eab..20c65d8b6 100644 --- a/platforms/android/samples/CheckoutKitAndroidDemo/app/src/main/java/com/shopify/checkout_kit_android_demo/cart/CartViewModel.kt +++ b/platforms/android/samples/CheckoutKitAndroidDemo/app/src/main/java/com/shopify/checkout_kit_android_demo/cart/CartViewModel.kt @@ -183,6 +183,7 @@ class CartViewModel( .on(CheckoutProtocol.totalsChange) { Timber.i("ECP ec.totals.change: $it") } .on(CheckoutProtocol.lineItemsChange) { Timber.i("ECP ec.line_items.change: $it") } .on(CheckoutProtocol.messagesChange) { Timber.i("ECP ec.messages.change: $it") } + .on(CheckoutProtocol.fulfillmentChange) { Timber.i("ECP ec.fulfillment.change: $it") } return when (windowOpenHandler) { WindowOpenHandler.Default -> base diff --git a/protocol/languages/kotlin/embedded-checkout-protocol/api/embedded-checkout-protocol.api b/protocol/languages/kotlin/embedded-checkout-protocol/api/embedded-checkout-protocol.api index 811f578cb..33fe0c5f9 100644 --- a/protocol/languages/kotlin/embedded-checkout-protocol/api/embedded-checkout-protocol.api +++ b/protocol/languages/kotlin/embedded-checkout-protocol/api/embedded-checkout-protocol.api @@ -627,6 +627,7 @@ public final class com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocol { public static final field SPEC_VERSION Ljava/lang/String; public final fun getComplete ()Lcom/shopify/ucp/embedded/checkout/NotificationDescriptor; public final fun getError ()Lcom/shopify/ucp/embedded/checkout/NotificationDescriptor; + public final fun getFulfillmentChange ()Lcom/shopify/ucp/embedded/checkout/NotificationDescriptor; public final fun getLineItemsChange ()Lcom/shopify/ucp/embedded/checkout/NotificationDescriptor; public final fun getMessagesChange ()Lcom/shopify/ucp/embedded/checkout/NotificationDescriptor; public final fun getStart ()Lcom/shopify/ucp/embedded/checkout/NotificationDescriptor; diff --git a/protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocol.kt b/protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocol.kt index 6e8e4db82..032415517 100644 --- a/protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocol.kt +++ b/protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocol.kt @@ -75,6 +75,9 @@ public object EmbeddedCheckoutProtocol { public val totalsChange: NotificationDescriptor get() = embeddedCheckoutTotalsChangeDescriptor + public val fulfillmentChange: NotificationDescriptor + get() = embeddedCheckoutFulfillmentChangeDescriptor + public val error: NotificationDescriptor get() = embeddedCheckoutErrorDescriptor diff --git a/protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocolDescriptors.kt b/protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocolDescriptors.kt index 1c4ca5969..e2ba31bee 100644 --- a/protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocolDescriptors.kt +++ b/protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocolDescriptors.kt @@ -13,6 +13,8 @@ internal val embeddedCheckoutLineItemsChangeDescriptor: NotificationDescriptor = checkoutDescriptor(EmbeddedCheckoutProtocol.Event.totalsChange) +internal val embeddedCheckoutFulfillmentChangeDescriptor: NotificationDescriptor = + checkoutDescriptor(EmbeddedCheckoutProtocol.Event.fulfillmentChange) internal val embeddedCheckoutErrorDescriptor: NotificationDescriptor = notificationDescriptor( method = EmbeddedCheckoutProtocol.Event.error, paramsSerializer = ErrorParams.serializer(), diff --git a/protocol/languages/kotlin/embedded-checkout-protocol/src/test/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocolTest.kt b/protocol/languages/kotlin/embedded-checkout-protocol/src/test/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocolTest.kt index acfb3de17..7f64c5d17 100644 --- a/protocol/languages/kotlin/embedded-checkout-protocol/src/test/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocolTest.kt +++ b/protocol/languages/kotlin/embedded-checkout-protocol/src/test/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocolTest.kt @@ -238,6 +238,14 @@ class EmbeddedCheckoutProtocolTest { assertThat(payload?.currency).isEqualTo("USD") } + @Test + fun `embedded checkout fulfillment change descriptor decodes checkout notifications`() { + val payload = EmbeddedCheckoutProtocol.fulfillmentChange.decode(Json.parseToJsonElement(checkoutParamsFixture)) + + assertThat(payload?.id).isEqualTo("checkout-123") + assertThat(payload?.currency).isEqualTo("USD") + } + @Test fun `embedded checkout descriptors decode error notifications`() { val payload = EmbeddedCheckoutProtocol.error.decode(Json.parseToJsonElement(errorParamsFixture)) diff --git a/protocol/scripts/generate_kotlin_catalog.mjs b/protocol/scripts/generate_kotlin_catalog.mjs index 810c29447..4c02a8bd7 100644 --- a/protocol/scripts/generate_kotlin_catalog.mjs +++ b/protocol/scripts/generate_kotlin_catalog.mjs @@ -190,6 +190,9 @@ ${delegations.map(delegation => ` ${delegation.identifier},`).joi public val totalsChange: NotificationDescriptor get() = embeddedCheckoutTotalsChangeDescriptor + public val fulfillmentChange: NotificationDescriptor + get() = embeddedCheckoutFulfillmentChangeDescriptor + public val error: NotificationDescriptor get() = embeddedCheckoutErrorDescriptor