From 151974b247ebbaf6c79607f0ba05e9a986ae5eae Mon Sep 17 00:00:00 2001 From: Daniel Kift Date: Fri, 22 May 2026 15:28:25 +0100 Subject: [PATCH] remove legacy-bridge --- platforms/android/AGENTS.md | 9 +- platforms/android/README.md | 23 +- platforms/android/lib/api/lib.api | 418 ------------------ .../com/shopify/checkoutkit/CheckoutBridge.kt | 110 ----- .../com/shopify/checkoutkit/CheckoutDialog.kt | 13 - .../shopify/checkoutkit/CheckoutWebView.kt | 12 +- .../checkoutkit/CheckoutWebViewListener.kt | 10 +- .../errorevents/CheckoutErrorDecoder.kt | 93 ---- .../errorevents/CheckoutErrorGroup.kt | 67 --- .../errorevents/CheckoutErrorPayload.kt | 34 -- .../CheckoutCompletedEventDecoder.kt | 47 -- .../lifecycleevents/CompletedEvent.kt | 131 ------ .../checkoutkit/lifecycleevents/MoneyV2.kt | 43 -- .../shopify/checkoutkit/CheckoutBridgeTest.kt | 247 ----------- .../CheckoutCompletedEventDecoderTest.kt | 339 -------------- .../checkoutkit/CheckoutWebViewTest.kt | 10 +- .../com/shopify/checkoutkit/InteropTest.java | 149 ------- .../errors/CheckoutErrorDecoderTest.kt | 166 ------- 18 files changed, 17 insertions(+), 1904 deletions(-) delete mode 100644 platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutBridge.kt delete mode 100644 platforms/android/lib/src/main/java/com/shopify/checkoutkit/errorevents/CheckoutErrorDecoder.kt delete mode 100644 platforms/android/lib/src/main/java/com/shopify/checkoutkit/errorevents/CheckoutErrorGroup.kt delete mode 100644 platforms/android/lib/src/main/java/com/shopify/checkoutkit/errorevents/CheckoutErrorPayload.kt delete mode 100644 platforms/android/lib/src/main/java/com/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEventDecoder.kt delete mode 100644 platforms/android/lib/src/main/java/com/shopify/checkoutkit/lifecycleevents/CompletedEvent.kt delete mode 100644 platforms/android/lib/src/main/java/com/shopify/checkoutkit/lifecycleevents/MoneyV2.kt delete mode 100644 platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutBridgeTest.kt delete mode 100644 platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutCompletedEventDecoderTest.kt delete mode 100644 platforms/android/lib/src/test/java/com/shopify/checkoutkit/errors/CheckoutErrorDecoderTest.kt diff --git a/platforms/android/AGENTS.md b/platforms/android/AGENTS.md index 3cbd7a6c..bf84ca1d 100644 --- a/platforms/android/AGENTS.md +++ b/platforms/android/AGENTS.md @@ -15,7 +15,7 @@ The sample is a separate Gradle composite (`samples/MobileBuyIntegration/setting ## Where to make changes -- Library source: `lib/src/main/java/com/shopify/checkoutkit/`. Flat package at the top level with a few subpackages (`errorevents/`, `lifecycleevents/`). +- Library source: `lib/src/main/java/com/shopify/checkoutkit/`. Flat package at the top level, including generated protocol models. - Library tests: `lib/src/test/java/com/shopify/checkoutkit/`. "No test, no merge" is a listed reject criterion in the repo-root `.github/CONTRIBUTING.md`. - Java interop is a first-class concern — the library is commonly consumed from Java code. `lib/src/test/java/com/shopify/checkoutkit/InteropTest.java` exercises the public API from Java specifically; treat breakage there as a consumer-facing issue. @@ -23,9 +23,9 @@ The sample is a separate Gradle composite (`samples/MobileBuyIntegration/setting - **`ShopifyCheckoutKit.kt`** — the public singleton. Entry point for all consumer interactions (configure, present). - **`CheckoutDialog.kt`** — the dialog that hosts the WebView, including the progress indicator and checkout error coordination. -- **`CheckoutWebView.kt`** — primary WebView. Instruments page loads; routes bridge messages. -- **`BaseWebView.kt`** — abstract base class. Any new WebView variant must extend this so shared configuration (JS interface name, user agent suffix, client handling) is consistent. -- **`CheckoutBridge.kt`** — the JS ↔ native bridge. `SCHEMA_VERSION` is a cross-boundary contract with the web checkout team; bumping it requires coordination with them. +- **`CheckoutWebView.kt`** — primary WebView. Instruments page loads and attaches the ECP JavaScript interface. +- **`BaseWebView.kt`** — abstract base class. Any new WebView variant must extend this so shared configuration (user agent suffix, WebChromeClient hooks, navigation error handling) is consistent. +- **`EmbeddedCheckoutProtocol.kt`** — the Embedded Checkout Protocol JavaScript interface. Handles `ec.ready`, ECP notifications, and request/response delegations. - **`Configuration.kt`** — runtime config container (color scheme, log level). - **`CheckoutListener.kt`** + **`DefaultCheckoutListener`** — consumer-implemented lifecycle interface (failure, cancellation, permission prompts, file chooser). Changes here are consumer API changes. - **`CheckoutPresentation.kt`** — Kotlin-first builder for per-presentation callbacks (`onFail`, `onCancel`, browser/system hooks, ECP `connect(...)`). Builds a `DefaultCheckoutListener` internally. @@ -94,5 +94,4 @@ Publishing goes through GitHub Releases → the repo-root `.github/workflows/and - **Library Kotlin version pin.** Consumer compatibility floor; any migration is a deliberate major-version decision. - **`minSdk` / JVM target.** Same story. -- **`CheckoutBridge.SCHEMA_VERSION`.** Cross-team contract with the web checkout — changing it without coordination breaks the bridge. - **`-Xexplicit-api=strict`.** Removing this would let implicit public declarations ship; keeping it is a consumer-protection invariant. diff --git a/platforms/android/README.md b/platforms/android/README.md index 7e7588aa..27e534fd 100644 --- a/platforms/android/README.md +++ b/platforms/android/README.md @@ -341,18 +341,9 @@ recreate the cart, retry later, or show an error state in the host app. | Exception Class | Error Code | Description | Recommendation | | ------------------------------ | ------------------------------ | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -| `ConfigurationException` | 'storefront_password_required' | Access to checkout is password protected. | We are working on ways to enable the Checkout Kit for usage with password protected stores. | -| `ConfigurationException` | 'unknown' | Other configuration issue, see error details for more info. | Resolve the configuration issue in the error message. | | `CheckoutExpiredException` | 'cart_expired' | The cart or checkout is no longer available. | Create a new cart and open a new checkout URL. | -| `CheckoutExpiredException` | 'cart_completed' | The cart associated with the checkout has completed checkout. | Create new cart and open a new checkout URL. | -| `CheckoutExpiredException` | 'invalid_cart' | The cart associated with the checkout is invalid (e.g. empty). | Create a new cart and open a new checkout URL. | -| `CheckoutKitException` | 'error_receiving_message' | Checkout Kit failed to receive a message from checkout. | Handle as a checkout failure in the host app. | -| `CheckoutKitException` | 'error_sending_message' | Checkout Kit failed to send a message to checkout. | Handle as a checkout failure in the host app. | -| `CheckoutKitException` | 'render_process_gone' | The render process for the checkout WebView is gone. | Handle as a checkout failure in the host app. | -| `CheckoutKitException` | 'unknown' | An error in Checkout Kit has occurred, see error details for more info. | Handle as a checkout failure in the host app. | +| `CheckoutKitException` | 'render_process_gone' | The render process for the checkout WebView is gone. | Handle as a checkout failure in the host app. | | `HttpException` | 'http_error' | An unexpected server error has been encountered. | Handle as a checkout failure in the host app. | -| `ClientException` | 'client_error' | An unhandled client error was encountered. | Handle as a checkout failure in the host app. | -| `CheckoutUnavailableException` | 'unknown' | Checkout is unavailable for another reason, see error details for more info. | Handle as a checkout failure in the host app. | #### Exception Hierarchy @@ -361,32 +352,24 @@ recreate the cart, retry later, or show an error state in the host app. title: Checkout Kit Exception Hierarchy --- classDiagram - CheckoutException <|-- ConfigurationException CheckoutException <|-- CheckoutExpiredException CheckoutException <|-- CheckoutKitException CheckoutException <|-- CheckoutUnavailableException CheckoutUnavailableException <|-- HttpException - CheckoutUnavailableException <|-- ClientException <> CheckoutException CheckoutException : +String errorDescription CheckoutException : +String errorCode - class ConfigurationException{ - note: "Store or checkout configuration issues." - } class CheckoutExpiredException{ - note: "Expired or invalid carts/checkouts." + note: "Expired checkouts." } class CheckoutUnavailableException{ - note: "Unexpected errors." + note: "Base class for availability failures." } class HttpException{ note: "Unexpected Http response" +int statusCode } - class ClientException{ - note: "Unexpected client/web error" - } class CheckoutKitException{ note: "Error in Checkout Kit code" } diff --git a/platforms/android/lib/api/lib.api b/platforms/android/lib/api/lib.api index 00901ae6..45727b35 100644 --- a/platforms/android/lib/api/lib.api +++ b/platforms/android/lib/api/lib.api @@ -4340,421 +4340,3 @@ public final class com/shopify/checkoutkit/WindowOpenResult$Success : com/shopif public static final field INSTANCE Lcom/shopify/checkoutkit/WindowOpenResult$Success; } -public final class com/shopify/checkoutkit/lifecycleevents/Address { - public static final field Companion Lcom/shopify/checkoutkit/lifecycleevents/Address$Companion; - public fun ()V - public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Ljava/lang/String; - public final fun component10 ()Ljava/lang/String; - public final fun component11 ()Ljava/lang/String; - public final fun component2 ()Ljava/lang/String; - public final fun component3 ()Ljava/lang/String; - public final fun component4 ()Ljava/lang/String; - public final fun component5 ()Ljava/lang/String; - public final fun component6 ()Ljava/lang/String; - public final fun component7 ()Ljava/lang/String; - public final fun component8 ()Ljava/lang/String; - public final fun component9 ()Ljava/lang/String; - public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/shopify/checkoutkit/lifecycleevents/Address; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/lifecycleevents/Address;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/shopify/checkoutkit/lifecycleevents/Address; - public fun equals (Ljava/lang/Object;)Z - public final fun getAddress1 ()Ljava/lang/String; - public final fun getAddress2 ()Ljava/lang/String; - public final fun getCity ()Ljava/lang/String; - public final fun getCountryCode ()Ljava/lang/String; - public final fun getFirstName ()Ljava/lang/String; - public final fun getLastName ()Ljava/lang/String; - public final fun getName ()Ljava/lang/String; - public final fun getPhone ()Ljava/lang/String; - public final fun getPostalCode ()Ljava/lang/String; - public final fun getReferenceId ()Ljava/lang/String; - public final fun getZoneCode ()Ljava/lang/String; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/shopify/checkoutkit/lifecycleevents/Address$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/shopify/checkoutkit/lifecycleevents/Address$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/shopify/checkoutkit/lifecycleevents/Address; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/shopify/checkoutkit/lifecycleevents/Address;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/Address$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/CartInfo { - public static final field Companion Lcom/shopify/checkoutkit/lifecycleevents/CartInfo$Companion; - public fun (Ljava/util/List;Lcom/shopify/checkoutkit/lifecycleevents/Price;Ljava/lang/String;)V - public final fun component1 ()Ljava/util/List; - public final fun component2 ()Lcom/shopify/checkoutkit/lifecycleevents/Price; - public final fun component3 ()Ljava/lang/String; - public final fun copy (Ljava/util/List;Lcom/shopify/checkoutkit/lifecycleevents/Price;Ljava/lang/String;)Lcom/shopify/checkoutkit/lifecycleevents/CartInfo; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/lifecycleevents/CartInfo;Ljava/util/List;Lcom/shopify/checkoutkit/lifecycleevents/Price;Ljava/lang/String;ILjava/lang/Object;)Lcom/shopify/checkoutkit/lifecycleevents/CartInfo; - public fun equals (Ljava/lang/Object;)Z - public final fun getLines ()Ljava/util/List; - public final fun getPrice ()Lcom/shopify/checkoutkit/lifecycleevents/Price; - public final fun getToken ()Ljava/lang/String; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/shopify/checkoutkit/lifecycleevents/CartInfo$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/shopify/checkoutkit/lifecycleevents/CartInfo$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/shopify/checkoutkit/lifecycleevents/CartInfo; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/shopify/checkoutkit/lifecycleevents/CartInfo;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/CartInfo$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/CartLine { - public static final field Companion Lcom/shopify/checkoutkit/lifecycleevents/CartLine$Companion; - public fun (Ljava/util/List;Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage;Ljava/lang/String;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Ljava/lang/String;ILjava/lang/String;)V - public synthetic fun (Ljava/util/List;Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage;Ljava/lang/String;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Ljava/lang/String;ILjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Ljava/util/List; - public final fun component2 ()Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage; - public final fun component3 ()Ljava/lang/String; - public final fun component4 ()Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public final fun component5 ()Ljava/lang/String; - public final fun component6 ()I - public final fun component7 ()Ljava/lang/String; - public final fun copy (Ljava/util/List;Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage;Ljava/lang/String;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Ljava/lang/String;ILjava/lang/String;)Lcom/shopify/checkoutkit/lifecycleevents/CartLine; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/lifecycleevents/CartLine;Ljava/util/List;Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage;Ljava/lang/String;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Ljava/lang/String;ILjava/lang/String;ILjava/lang/Object;)Lcom/shopify/checkoutkit/lifecycleevents/CartLine; - public fun equals (Ljava/lang/Object;)Z - public final fun getDiscounts ()Ljava/util/List; - public final fun getImage ()Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage; - public final fun getMerchandiseId ()Ljava/lang/String; - public final fun getPrice ()Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public final fun getProductId ()Ljava/lang/String; - public final fun getQuantity ()I - public final fun getTitle ()Ljava/lang/String; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/shopify/checkoutkit/lifecycleevents/CartLine$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/shopify/checkoutkit/lifecycleevents/CartLine$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/shopify/checkoutkit/lifecycleevents/CartLine; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/shopify/checkoutkit/lifecycleevents/CartLine;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/CartLine$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/CartLineImage { - public static final field Companion Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage$Companion; - public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Ljava/lang/String; - public final fun component2 ()Ljava/lang/String; - public final fun component3 ()Ljava/lang/String; - public final fun component4 ()Ljava/lang/String; - public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage; - public fun equals (Ljava/lang/Object;)Z - public final fun getAltText ()Ljava/lang/String; - public final fun getLg ()Ljava/lang/String; - public final fun getMd ()Ljava/lang/String; - public final fun getSm ()Ljava/lang/String; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/shopify/checkoutkit/lifecycleevents/CartLineImage$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/shopify/checkoutkit/lifecycleevents/CartLineImage;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/CartLineImage$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEvent { - public static final field Companion Lcom/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEvent$Companion; - public fun (Lcom/shopify/checkoutkit/lifecycleevents/OrderDetails;)V - public final fun component1 ()Lcom/shopify/checkoutkit/lifecycleevents/OrderDetails; - public final fun copy (Lcom/shopify/checkoutkit/lifecycleevents/OrderDetails;)Lcom/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEvent; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEvent;Lcom/shopify/checkoutkit/lifecycleevents/OrderDetails;ILjava/lang/Object;)Lcom/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEvent; - public fun equals (Ljava/lang/Object;)Z - public final fun getOrderDetails ()Lcom/shopify/checkoutkit/lifecycleevents/OrderDetails; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEvent$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEvent$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEvent; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEvent;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEvent$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/DeliveryDetails { - public static final field Companion Lcom/shopify/checkoutkit/lifecycleevents/DeliveryDetails$Companion; - public fun ()V - public fun (Ljava/lang/String;Lcom/shopify/checkoutkit/lifecycleevents/Address;Ljava/lang/String;)V - public synthetic fun (Ljava/lang/String;Lcom/shopify/checkoutkit/lifecycleevents/Address;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Ljava/lang/String; - public final fun component2 ()Lcom/shopify/checkoutkit/lifecycleevents/Address; - public final fun component3 ()Ljava/lang/String; - public final fun copy (Ljava/lang/String;Lcom/shopify/checkoutkit/lifecycleevents/Address;Ljava/lang/String;)Lcom/shopify/checkoutkit/lifecycleevents/DeliveryDetails; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/lifecycleevents/DeliveryDetails;Ljava/lang/String;Lcom/shopify/checkoutkit/lifecycleevents/Address;Ljava/lang/String;ILjava/lang/Object;)Lcom/shopify/checkoutkit/lifecycleevents/DeliveryDetails; - public fun equals (Ljava/lang/Object;)Z - public final fun getAdditionalInfo ()Ljava/lang/String; - public final fun getLocation ()Lcom/shopify/checkoutkit/lifecycleevents/Address; - public final fun getName ()Ljava/lang/String; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/shopify/checkoutkit/lifecycleevents/DeliveryDetails$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/shopify/checkoutkit/lifecycleevents/DeliveryDetails$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/shopify/checkoutkit/lifecycleevents/DeliveryDetails; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/shopify/checkoutkit/lifecycleevents/DeliveryDetails;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/DeliveryDetails$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/DeliveryInfo { - public static final field Companion Lcom/shopify/checkoutkit/lifecycleevents/DeliveryInfo$Companion; - public fun (Lcom/shopify/checkoutkit/lifecycleevents/DeliveryDetails;Ljava/lang/String;)V - public final fun component1 ()Lcom/shopify/checkoutkit/lifecycleevents/DeliveryDetails; - public final fun component2 ()Ljava/lang/String; - public final fun copy (Lcom/shopify/checkoutkit/lifecycleevents/DeliveryDetails;Ljava/lang/String;)Lcom/shopify/checkoutkit/lifecycleevents/DeliveryInfo; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/lifecycleevents/DeliveryInfo;Lcom/shopify/checkoutkit/lifecycleevents/DeliveryDetails;Ljava/lang/String;ILjava/lang/Object;)Lcom/shopify/checkoutkit/lifecycleevents/DeliveryInfo; - public fun equals (Ljava/lang/Object;)Z - public final fun getDetails ()Lcom/shopify/checkoutkit/lifecycleevents/DeliveryDetails; - public final fun getMethod ()Ljava/lang/String; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/shopify/checkoutkit/lifecycleevents/DeliveryInfo$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/shopify/checkoutkit/lifecycleevents/DeliveryInfo$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/shopify/checkoutkit/lifecycleevents/DeliveryInfo; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/shopify/checkoutkit/lifecycleevents/DeliveryInfo;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/DeliveryInfo$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/Discount { - public static final field Companion Lcom/shopify/checkoutkit/lifecycleevents/Discount$Companion; - public fun ()V - public fun (Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Double;Ljava/lang/String;)V - public synthetic fun (Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Double;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public final fun component2 ()Ljava/lang/String; - public final fun component3 ()Ljava/lang/String; - public final fun component4 ()Ljava/lang/Double; - public final fun component5 ()Ljava/lang/String; - public final fun copy (Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Double;Ljava/lang/String;)Lcom/shopify/checkoutkit/lifecycleevents/Discount; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/lifecycleevents/Discount;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Double;Ljava/lang/String;ILjava/lang/Object;)Lcom/shopify/checkoutkit/lifecycleevents/Discount; - public fun equals (Ljava/lang/Object;)Z - public final fun getAmount ()Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public final fun getApplicationType ()Ljava/lang/String; - public final fun getTitle ()Ljava/lang/String; - public final fun getValue ()Ljava/lang/Double; - public final fun getValueType ()Ljava/lang/String; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/shopify/checkoutkit/lifecycleevents/Discount$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/shopify/checkoutkit/lifecycleevents/Discount$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/shopify/checkoutkit/lifecycleevents/Discount; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/shopify/checkoutkit/lifecycleevents/Discount;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/Discount$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/MoneyV2 { - public static final field Companion Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2$Companion; - public fun ()V - public fun (Ljava/lang/Double;Ljava/lang/String;)V - public synthetic fun (Ljava/lang/Double;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Ljava/lang/Double; - public final fun component2 ()Ljava/lang/String; - public final fun copy (Ljava/lang/Double;Ljava/lang/String;)Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Ljava/lang/Double;Ljava/lang/String;ILjava/lang/Object;)Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public fun equals (Ljava/lang/Object;)Z - public final fun getAmount ()Ljava/lang/Double; - public final fun getCurrencyCode ()Ljava/lang/String; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/shopify/checkoutkit/lifecycleevents/MoneyV2$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/MoneyV2$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/OrderDetails { - public static final field Companion Lcom/shopify/checkoutkit/lifecycleevents/OrderDetails$Companion; - public fun (Lcom/shopify/checkoutkit/lifecycleevents/Address;Lcom/shopify/checkoutkit/lifecycleevents/CartInfo;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;)V - public synthetic fun (Lcom/shopify/checkoutkit/lifecycleevents/Address;Lcom/shopify/checkoutkit/lifecycleevents/CartInfo;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Lcom/shopify/checkoutkit/lifecycleevents/Address; - public final fun component2 ()Lcom/shopify/checkoutkit/lifecycleevents/CartInfo; - public final fun component3 ()Ljava/util/List; - public final fun component4 ()Ljava/lang/String; - public final fun component5 ()Ljava/lang/String; - public final fun component6 ()Ljava/util/List; - public final fun component7 ()Ljava/lang/String; - public final fun copy (Lcom/shopify/checkoutkit/lifecycleevents/Address;Lcom/shopify/checkoutkit/lifecycleevents/CartInfo;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;)Lcom/shopify/checkoutkit/lifecycleevents/OrderDetails; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/lifecycleevents/OrderDetails;Lcom/shopify/checkoutkit/lifecycleevents/Address;Lcom/shopify/checkoutkit/lifecycleevents/CartInfo;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;ILjava/lang/Object;)Lcom/shopify/checkoutkit/lifecycleevents/OrderDetails; - public fun equals (Ljava/lang/Object;)Z - public final fun getBillingAddress ()Lcom/shopify/checkoutkit/lifecycleevents/Address; - public final fun getCart ()Lcom/shopify/checkoutkit/lifecycleevents/CartInfo; - public final fun getDeliveries ()Ljava/util/List; - public final fun getEmail ()Ljava/lang/String; - public final fun getId ()Ljava/lang/String; - public final fun getPaymentMethods ()Ljava/util/List; - public final fun getPhone ()Ljava/lang/String; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/shopify/checkoutkit/lifecycleevents/OrderDetails$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/shopify/checkoutkit/lifecycleevents/OrderDetails$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/shopify/checkoutkit/lifecycleevents/OrderDetails; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/shopify/checkoutkit/lifecycleevents/OrderDetails;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/OrderDetails$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/PaymentMethod { - public static final field Companion Lcom/shopify/checkoutkit/lifecycleevents/PaymentMethod$Companion; - public fun (Ljava/util/Map;Ljava/lang/String;)V - public synthetic fun (Ljava/util/Map;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Ljava/util/Map; - public final fun component2 ()Ljava/lang/String; - public final fun copy (Ljava/util/Map;Ljava/lang/String;)Lcom/shopify/checkoutkit/lifecycleevents/PaymentMethod; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/lifecycleevents/PaymentMethod;Ljava/util/Map;Ljava/lang/String;ILjava/lang/Object;)Lcom/shopify/checkoutkit/lifecycleevents/PaymentMethod; - public fun equals (Ljava/lang/Object;)Z - public final fun getDetails ()Ljava/util/Map; - public final fun getType ()Ljava/lang/String; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/shopify/checkoutkit/lifecycleevents/PaymentMethod$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/shopify/checkoutkit/lifecycleevents/PaymentMethod$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/shopify/checkoutkit/lifecycleevents/PaymentMethod; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/shopify/checkoutkit/lifecycleevents/PaymentMethod;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/PaymentMethod$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/Price { - public static final field Companion Lcom/shopify/checkoutkit/lifecycleevents/Price$Companion; - public fun ()V - public fun (Ljava/util/List;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;)V - public synthetic fun (Ljava/util/List;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Ljava/util/List; - public final fun component2 ()Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public final fun component3 ()Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public final fun component4 ()Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public final fun component5 ()Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public final fun copy (Ljava/util/List;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;)Lcom/shopify/checkoutkit/lifecycleevents/Price; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/lifecycleevents/Price;Ljava/util/List;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2;ILjava/lang/Object;)Lcom/shopify/checkoutkit/lifecycleevents/Price; - public fun equals (Ljava/lang/Object;)Z - public final fun getDiscounts ()Ljava/util/List; - public final fun getShipping ()Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public final fun getSubtotal ()Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public final fun getTaxes ()Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public final fun getTotal ()Lcom/shopify/checkoutkit/lifecycleevents/MoneyV2; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/shopify/checkoutkit/lifecycleevents/Price$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/shopify/checkoutkit/lifecycleevents/Price$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/shopify/checkoutkit/lifecycleevents/Price; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/shopify/checkoutkit/lifecycleevents/Price;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/shopify/checkoutkit/lifecycleevents/Price$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - diff --git a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutBridge.kt b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutBridge.kt deleted file mode 100644 index 8142bf57..00000000 --- a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutBridge.kt +++ /dev/null @@ -1,110 +0,0 @@ -/* - * MIT License - * - * Copyright 2023-present, Shopify Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.shopify.checkoutkit - -import android.webkit.JavascriptInterface -import com.shopify.checkoutkit.CheckoutBridge.CheckoutWebOperation.ERROR -import com.shopify.checkoutkit.CheckoutBridge.CheckoutWebOperation.MODAL -import com.shopify.checkoutkit.ShopifyCheckoutKit.log -import com.shopify.checkoutkit.errorevents.CheckoutErrorDecoder -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json - -internal class CheckoutBridge( - private var listener: CheckoutWebViewListener, - private val decoder: Json = Json { ignoreUnknownKeys = true }, - private val checkoutErrorDecoder: CheckoutErrorDecoder = CheckoutErrorDecoder(decoder, log), -) { - - fun setListener(listener: CheckoutWebViewListener) { - this.listener = listener - } - - fun getListener(): CheckoutWebViewListener = this.listener - - enum class CheckoutWebOperation(val key: String) { - MODAL("checkoutBlockingEvent"), - ERROR("error"); - - companion object { - fun fromKey(key: String): CheckoutWebOperation? { - return entries.find { it.key == key } - } - } - } - - // Allows Web to postMessages back to the SDK - @Suppress("SwallowedException") - @JavascriptInterface - fun postMessage(message: String) { - try { - log.d(LOG_TAG, "Received message from checkout.") - val decodedMsg = decoder.decodeFromString(message) - - when (CheckoutWebOperation.fromKey(decodedMsg.name)) { - MODAL -> { - log.d(LOG_TAG, "Received Modal message.") - val modalVisible = decodedMsg.body.toBooleanStrictOrNull() - modalVisible?.let { - log.d(LOG_TAG, "Modal visible $it") - onMainThread { - listener.onCheckoutViewModalToggled(modalVisible) - } - } - } - - ERROR -> { - log.d(LOG_TAG, "Received Error message. Attempting to decode.") - checkoutErrorDecoder.decode(decodedMsg)?.let { exception -> - log.d(LOG_TAG, "Decoded message $exception.") - onMainThread { - listener.onCheckoutViewFailedWithError(exception) - } - } - } - - else -> {} - } - } catch (e: Exception) { - log.d(LOG_TAG, "Failed to decode message with error: $e. Calling onCheckoutFailedWithError") - onMainThread { - listener.onCheckoutViewFailedWithError( - CheckoutKitException( - errorDescription = "Error decoding message from checkout.", - errorCode = CheckoutKitException.ERROR_RECEIVING_MESSAGE_FROM_CHECKOUT, - ), - ) - } - } - } - - companion object { - private const val LOG_TAG = "CheckoutBridge" - } -} - -@Serializable -internal data class WebToSdkEvent( - val name: String, - val body: String = "" -) diff --git a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutDialog.kt b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutDialog.kt index d772e804..d29ef678 100644 --- a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutDialog.kt +++ b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutDialog.kt @@ -28,12 +28,8 @@ import android.content.res.Configuration.UI_MODE_NIGHT_MASK import android.content.res.Configuration.UI_MODE_NIGHT_YES import android.graphics.Color import android.os.Build -import android.os.Handler -import android.os.Looper import android.view.MenuItem -import android.view.View.GONE import android.view.View.INVISIBLE -import android.view.View.VISIBLE import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.view.WindowManager @@ -173,14 +169,6 @@ internal class CheckoutDialog( } } - private fun toggleHeader(modalVisible: Boolean) { - Handler(Looper.getMainLooper()).post { - log.d(LOG_TAG, "Toggling header based on modal visibility state. Modal visible: $modalVisible.") - findViewById(R.id.checkoutKitHeader).visibility = if (modalVisible) GONE else VISIBLE - findViewById(R.id.progressBar).visibility = if (modalVisible) GONE else INVISIBLE - } - } - private fun updateProgressBarPercentage(percentage: Int) { log.d(LOG_TAG, "Updating progress bar percentage, $percentage.") if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { @@ -204,7 +192,6 @@ internal class CheckoutDialog( private fun webViewListener(): CheckoutWebViewListener { return CheckoutWebViewListener( listener = checkoutListener, - toggleHeader = ::toggleHeader, closeCheckoutDialogWithError = ::closeCheckoutDialogWithError, setProgressBarVisibility = ::setProgressBarVisibility, updateProgressBarPercentage = ::updateProgressBarPercentage, diff --git a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutWebView.kt b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutWebView.kt index a5af429e..2ed0ef16 100644 --- a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutWebView.kt +++ b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutWebView.kt @@ -34,13 +34,12 @@ import com.shopify.checkoutkit.ShopifyCheckoutKit.log internal class CheckoutWebView(context: Context, attributeSet: AttributeSet? = null) : BaseWebView(context, attributeSet) { - private val checkoutBridge = CheckoutBridge(CheckoutWebViewListener(NoopCheckoutListener())) + private var listener = CheckoutWebViewListener(NoopCheckoutListener()) private val embeddedCheckoutProtocol = EmbeddedCheckoutProtocol(this) private var loadComplete = false init { webViewClient = CheckoutWebViewClient() - addJavascriptInterface(checkoutBridge, JAVASCRIPT_INTERFACE_NAME) addJavascriptInterface(embeddedCheckoutProtocol, EmbeddedCheckoutProtocol.INTERFACE_NAME) settings.userAgentString = "${settings.userAgentString} ${userAgentSuffix()}" } @@ -49,7 +48,7 @@ internal class CheckoutWebView(context: Context, attributeSet: AttributeSet? = n fun setListener(listener: CheckoutWebViewListener) { log.d(LOG_TAG, "Setting listener $listener.") - checkoutBridge.setListener(listener) + this.listener = listener } fun setClient(client: CheckoutCommunicationClient?) { @@ -58,20 +57,18 @@ internal class CheckoutWebView(context: Context, attributeSet: AttributeSet? = n } override fun getListener(): CheckoutWebViewListener { - return checkoutBridge.getListener() + return listener } override fun onAttachedToWindow() { super.onAttachedToWindow() log.d(LOG_TAG, "Attached to window. Adding JavaScript interfaces.") - addJavascriptInterface(checkoutBridge, JAVASCRIPT_INTERFACE_NAME) addJavascriptInterface(embeddedCheckoutProtocol, EmbeddedCheckoutProtocol.INTERFACE_NAME) } override fun onDetachedFromWindow() { super.onDetachedFromWindow() log.d(LOG_TAG, "Detached from window. Removing JavaScript interfaces.") - removeJavascriptInterface(JAVASCRIPT_INTERFACE_NAME) removeJavascriptInterface(EmbeddedCheckoutProtocol.INTERFACE_NAME) } @@ -88,7 +85,7 @@ internal class CheckoutWebView(context: Context, attributeSet: AttributeSet? = n override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { super.onPageStarted(view, url, favicon) log.d(LOG_TAG, "onPageStarted called $url.") - checkoutBridge.getListener().onCheckoutViewLoadStarted() + getListener().onCheckoutViewLoadStarted() } override fun onPageFinished(view: WebView, url: String) { @@ -117,6 +114,5 @@ internal class CheckoutWebView(context: Context, attributeSet: AttributeSet? = n companion object { private const val LOG_TAG = "CheckoutWebView" - private const val JAVASCRIPT_INTERFACE_NAME = "android" } } diff --git a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutWebViewListener.kt b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutWebViewListener.kt index e1c989a2..825cdd31 100644 --- a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutWebViewListener.kt +++ b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutWebViewListener.kt @@ -33,22 +33,14 @@ import android.webkit.WebView /** * Internal wrapper around the consumer-provided CheckoutListener. Handles dialog-internal - * behavior (progress bar, modal header toggling, error close) and delegates the rest to - * the listener. + * behavior (progress bar and error close) and delegates the rest to the listener. */ internal class CheckoutWebViewListener( private val listener: CheckoutListener, - private val toggleHeader: (Boolean) -> Unit = {}, private val closeCheckoutDialogWithError: (CheckoutException) -> Unit = {}, private val setProgressBarVisibility: (Int) -> Unit = {}, private val updateProgressBarPercentage: (Int) -> Unit = {}, ) { - fun onCheckoutViewModalToggled(modalVisible: Boolean) { - onMainThread { - toggleHeader(modalVisible) - } - } - fun onCheckoutViewFailedWithError(error: CheckoutException) { onMainThread { closeCheckoutDialogWithError(error) diff --git a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/errorevents/CheckoutErrorDecoder.kt b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/errorevents/CheckoutErrorDecoder.kt deleted file mode 100644 index c177f29e..00000000 --- a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/errorevents/CheckoutErrorDecoder.kt +++ /dev/null @@ -1,93 +0,0 @@ -/* - * MIT License - * - * Copyright 2023-present, Shopify Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.shopify.checkoutkit.errorevents - -import com.shopify.checkoutkit.CheckoutException -import com.shopify.checkoutkit.CheckoutExpiredException -import com.shopify.checkoutkit.ClientException -import com.shopify.checkoutkit.ConfigurationException -import com.shopify.checkoutkit.LogWrapper -import com.shopify.checkoutkit.WebToSdkEvent -import kotlinx.serialization.json.Json - -internal class CheckoutErrorDecoder @JvmOverloads constructor( - private val decoder: Json, - private val log: LogWrapper = LogWrapper() -) { - fun decode(message: WebToSdkEvent): CheckoutException? = try { - decodeMessage(message).mapToCheckoutException() - } catch (e: Exception) { - log.e("CheckoutBridge", "Failed to decode CheckoutErrorPayload", e) - throw e - } - - internal fun decodeMessage(message: WebToSdkEvent): CheckoutErrorPayload { - val errors = decoder.decodeFromString>(message.body) - return errors.first() - } - - private fun CheckoutErrorPayload.mapToCheckoutException(): CheckoutException? { - return when (this.group) { - CheckoutErrorGroup.CONFIGURATION -> { - ConfigurationException( - errorDescription = this.reason ?: "Storefront configuration error.", - errorCode = if (this.code == STOREFRONT_PASSWORD_REQUIRED) { - ConfigurationException.STOREFRONT_PASSWORD_REQUIRED - } else { - ConfigurationException.UNKNOWN - }, - ) - } - - CheckoutErrorGroup.UNRECOVERABLE -> - ClientException( - errorDescription = this.reason, - ) - - CheckoutErrorGroup.EXPIRED -> - CheckoutExpiredException( - errorDescription = this.reason, - errorCode = this.expiredErrorCode(), - ) - - else -> { - // The remaining error groups are unsupported and will be ignored - null - } - } - } - - private fun CheckoutErrorPayload.expiredErrorCode(): String { - return when (this.code) { - INVALID_CART -> CheckoutExpiredException.INVALID_CART - CART_COMPLETED -> CheckoutExpiredException.CART_COMPLETED - else -> CheckoutExpiredException.CART_EXPIRED - } - } - - companion object { - private const val STOREFRONT_PASSWORD_REQUIRED = "storefront_password_required" - private const val INVALID_CART = "invalid_cart" - private const val CART_COMPLETED = "cart_completed" - } -} diff --git a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/errorevents/CheckoutErrorGroup.kt b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/errorevents/CheckoutErrorGroup.kt deleted file mode 100644 index f25b7e4f..00000000 --- a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/errorevents/CheckoutErrorGroup.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * MIT License - * - * Copyright 2023-present, Shopify Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.shopify.checkoutkit.errorevents - -import kotlinx.serialization.KSerializer -import kotlinx.serialization.Serializable -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder - -@Serializable(with = CheckoutErrorGroupSerializer::class) -internal enum class CheckoutErrorGroup(val value: String) { - /** An authentication error */ - AUTHENTICATION("authentication"), - - /** A shop configuration error */ - CONFIGURATION("configuration"), - - /** A terminal checkout error which cannot be handled */ - UNRECOVERABLE("unrecoverable"), - - /** A checkout-related error, such as failure to receive a receipt or progress through checkout */ - CHECKOUT("checkout"), - - /** The checkout session has expired and is no longer available */ - EXPIRED("expired"), - - /** The error sent by checkout is unsupported */ - UNSUPPORTED("unsupported") -} - -internal object CheckoutErrorGroupSerializer : KSerializer { - override val descriptor: SerialDescriptor = - PrimitiveSerialDescriptor("ErrorGroup", PrimitiveKind.STRING) - - override fun serialize(encoder: Encoder, value: CheckoutErrorGroup) { - encoder.encodeString(value.value) - } - - override fun deserialize(decoder: Decoder): CheckoutErrorGroup { - val value = decoder.decodeString() - return CheckoutErrorGroup.entries.firstOrNull { it.value == value } - ?: CheckoutErrorGroup.UNSUPPORTED - } -} diff --git a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/errorevents/CheckoutErrorPayload.kt b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/errorevents/CheckoutErrorPayload.kt deleted file mode 100644 index 4d28b4df..00000000 --- a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/errorevents/CheckoutErrorPayload.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * MIT License - * - * Copyright 2023-present, Shopify Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.shopify.checkoutkit.errorevents - -import kotlinx.serialization.Serializable - -@Serializable -internal data class CheckoutErrorPayload( - val group: CheckoutErrorGroup, - val code: String? = null, - val flowType: String? = null, - val reason: String? = null, - val type: String? = null, -) diff --git a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEventDecoder.kt b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEventDecoder.kt deleted file mode 100644 index 4a40360c..00000000 --- a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/lifecycleevents/CheckoutCompletedEventDecoder.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * MIT License - * - * Copyright 2023-present, Shopify Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.shopify.checkoutkit.lifecycleevents - -import com.shopify.checkoutkit.LogWrapper -import com.shopify.checkoutkit.WebToSdkEvent -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json - -@Serializable -public data class CheckoutCompletedEvent( - public val orderDetails: OrderDetails -) - -internal class CheckoutCompletedEventDecoder @JvmOverloads constructor( - private val decoder: Json, - private val log: LogWrapper = LogWrapper() -) { - fun decode(decodedMsg: WebToSdkEvent): CheckoutCompletedEvent { - return try { - decoder.decodeFromString(decodedMsg.body) - } catch (e: Exception) { - log.e("CheckoutBridge", "Failed to decode CheckoutCompleted event", e) - emptyCompletedEvent() - } - } -} diff --git a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/lifecycleevents/CompletedEvent.kt b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/lifecycleevents/CompletedEvent.kt deleted file mode 100644 index 5997e288..00000000 --- a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/lifecycleevents/CompletedEvent.kt +++ /dev/null @@ -1,131 +0,0 @@ -/* - * MIT License - * - * Copyright 2023-present, Shopify Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.shopify.checkoutkit.lifecycleevents - -import kotlinx.serialization.Serializable - -@Serializable -public data class Address( - public val address1: String? = null, - public val address2: String? = null, - public val city: String? = null, - public val countryCode: String? = null, - public val firstName: String? = null, - public val lastName: String? = null, - public val name: String? = null, - public val phone: String? = null, - public val postalCode: String? = null, - public val referenceId: String? = null, - public val zoneCode: String? = null, -) - -@Serializable -public data class CartInfo( - public val lines: List, - public val price: Price, - public val token: String, -) - -@Serializable -public data class CartLineImage( - public val altText: String? = null, - public val lg: String, - public val md: String, - public val sm: String, -) - -@Serializable -public data class CartLine( - public val discounts: List? = emptyList(), - public val image: CartLineImage? = null, - public val merchandiseId: String? = null, - public val price: MoneyV2, - public val productId: String? = null, - public val quantity: Int, - public val title: String, -) - -@Serializable -public data class DeliveryDetails( - public val additionalInfo: String? = null, - public val location: Address? = null, - public val name: String? = null, -) - -/** - * Current possible methods: - * SHIPPING, PICK_UP, RETAIL, LOCAL, PICKUP_POINT, NONE - */ -@Serializable -public data class DeliveryInfo( - public val details: DeliveryDetails, - public val method: String, -) - -@Serializable -public data class Discount( - public val amount: MoneyV2? = null, - public val applicationType: String? = null, - public val title: String? = null, - public val value: Double? = null, - public val valueType: String? = null, -) - -@Serializable -public data class OrderDetails( - public val billingAddress: Address? = null, - public val cart: CartInfo, - public val deliveries: List = emptyList(), - public val email: String? = null, - public val id: String, - public val paymentMethods: List = emptyList(), - public val phone: String? = null, -) - -@Serializable -public data class PaymentMethod( - public val details: Map? = emptyMap(), - public val type: String, -) - -@Serializable -public data class Price( - public val discounts: List? = emptyList(), - public val shipping: MoneyV2? = null, - public val subtotal: MoneyV2? = null, - public val taxes: MoneyV2? = null, - public val total: MoneyV2? = null, -) - -internal fun emptyCompletedEvent(id: String? = null): CheckoutCompletedEvent { - return CheckoutCompletedEvent( - orderDetails = OrderDetails( - cart = CartInfo( - token = "", - lines = emptyList(), - price = Price() - ), - id = id ?: "", - ) - ) -} diff --git a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/lifecycleevents/MoneyV2.kt b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/lifecycleevents/MoneyV2.kt deleted file mode 100644 index c330f5c1..00000000 --- a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/lifecycleevents/MoneyV2.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * MIT License - * - * Copyright 2023-present, Shopify Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.shopify.checkoutkit.lifecycleevents - -import kotlinx.serialization.Serializable - -/** - * A monetary value with currency. - */ -@Serializable -public data class MoneyV2( - /** - * The decimal money amount. - */ - public val amount: Double? = null, - - /** - * The three-letter code that represents the currency, for example, USD. - * Supported codes include standard ISO 4217 codes, legacy codes, and non- - * standard codes. - */ - public val currencyCode: String? = null, -) diff --git a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutBridgeTest.kt b/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutBridgeTest.kt deleted file mode 100644 index 99cb1b65..00000000 --- a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutBridgeTest.kt +++ /dev/null @@ -1,247 +0,0 @@ -/* - * MIT License - * - * Copyright 2023-present, Shopify Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.shopify.checkoutkit - -import com.shopify.checkoutkit.CheckoutBridge.CheckoutWebOperation.MODAL -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import org.assertj.core.api.Assertions.assertThat -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.kotlin.argumentCaptor -import org.mockito.kotlin.mock -import org.mockito.kotlin.timeout -import org.mockito.kotlin.verify -import org.mockito.kotlin.verifyNoInteractions -import org.robolectric.RobolectricTestRunner - -@RunWith(RobolectricTestRunner::class) -class CheckoutBridgeTest { - - private var mockListener = mock() - private lateinit var checkoutBridge: CheckoutBridge - - @Before - fun init() { - checkoutBridge = CheckoutBridge(mockListener) - } - - @Test - fun `postMessage calls web event processor onCheckoutModalToggled when modal message received - false`() { - checkoutBridge.postMessage( - Json.encodeToString( - WebToSdkEvent( - MODAL.key, - "false" - ) - ) - ) - verify(mockListener).onCheckoutViewModalToggled(false) - } - - @Test - fun `postMessage calls web event processor onCheckoutModalToggled when modal message received - true`() { - checkoutBridge.postMessage( - Json.encodeToString( - WebToSdkEvent( - MODAL.key, - "true" - ) - ) - ) - verify(mockListener).onCheckoutViewModalToggled(true) - } - - @Test - fun `postMessage does not issue a msg to the event processor when unsupported message received`() { - checkoutBridge.postMessage(Json.encodeToString(WebToSdkEvent("boom"))) - verifyNoInteractions(mockListener) - } - - @Test - fun `should decode a checkout expired error payload and call processor#onCheckoutViewFailedWithError - invalid`() { - val eventString = """| - |{ - | "name":"error", - | "body": "[{ - | \"group\": \"expired\", - | \"reason\": \"Cart is invalid\", - | \"flowType\": \"regular\", - | \"code\": \"invalid_cart\" - | }]" - |} - | - """.trimMargin() - - checkoutBridge.postMessage(eventString) - - val captor = argumentCaptor() - verify(mockListener, timeout(2000).times(1)).onCheckoutViewFailedWithError(captor.capture()) - - val error = captor.firstValue - assertThat(error).isInstanceOf(CheckoutExpiredException::class.java) - assertThat(error.message).isEqualTo("Cart is invalid") - assertThat(error.errorCode).isEqualTo(CheckoutExpiredException.INVALID_CART) - } - - @Test - fun `should decode a checkout expired error payload and call processor#onCheckoutViewFailedWithError - completed`() { - val eventString = """| - |{ - | "name":"error", - | "body": "[{ - | \"group\": \"expired\", - | \"reason\": \"Checkout has been completed\", - | \"flowType\": \"regular\", - | \"code\": \"cart_completed\" - | }]" - |} - | - """.trimMargin() - - checkoutBridge.postMessage(eventString) - - val captor = argumentCaptor() - verify(mockListener, timeout(2000).times(1)).onCheckoutViewFailedWithError(captor.capture()) - - val error = captor.firstValue - assertThat(error).isInstanceOf(CheckoutExpiredException::class.java) - assertThat(error.message).isEqualTo("Checkout has been completed") - assertThat(error.errorCode).isEqualTo(CheckoutExpiredException.CART_COMPLETED) - } - - @Test - fun `should decode a barebones expired error payload and call processor#onCheckoutViewFailedWithError`() { - val eventString = """| - |{ - | "name": "error", - | "body": "[{ - | \"group\": \"expired\" - | }]" - |} - | - """.trimMargin() - - checkoutBridge.postMessage(eventString) - - val captor = argumentCaptor() - verify(mockListener, timeout(2000).times(1)).onCheckoutViewFailedWithError(captor.capture()) - - val error = captor.firstValue - assertThat(error).isInstanceOf(CheckoutExpiredException::class.java) - assertThat(error.message).isEqualTo( - "Checkout is no longer available with the provided token. Please generate a new checkout URL" - ) - assertThat(error.errorCode).isEqualTo(CheckoutExpiredException.CART_EXPIRED) - } - - @Test - fun `should decode an unrecoverable error payload and call processor#onCheckoutViewFailedWithError`() { - val eventString = """| - |{ - | "name":"error", - | "body": "[{ - | \"group\": \"unrecoverable\", - | \"reason\": \"Checkout crashed\", - | \"code\": \"sdk_not_enabled\" - | }]" - |} - | - """.trimMargin() - - checkoutBridge.postMessage(eventString) - - val captor = argumentCaptor() - verify(mockListener, timeout(2000).times(1)).onCheckoutViewFailedWithError(captor.capture()) - - val error = captor.firstValue - assertThat(error).isInstanceOf(CheckoutUnavailableException::class.java) - assertThat(error.message).isEqualTo("Checkout crashed") - assertThat(error.errorCode).isEqualTo(CheckoutUnavailableException.CLIENT_ERROR) - } - - @Test - fun `should decode a configuration error payload and call processor#onCheckoutViewFailedWithError - storefront pw required`() { - val eventString = """| - |{ - | "name":"error", - | "body": "[{ - | \"group\": \"configuration\", - | \"reason\": \"Storefront password required\", - | \"code\": \"storefront_password_required\" - | }]" - |} - | - """.trimMargin() - - checkoutBridge.postMessage(eventString) - - val captor = argumentCaptor() - verify(mockListener, timeout(2000).times(1)).onCheckoutViewFailedWithError(captor.capture()) - - val error = captor.firstValue - assertThat(error).isInstanceOf(ConfigurationException::class.java) - assertThat(error.message).isEqualTo("Storefront password required") - assertThat(error.errorCode).isEqualTo(ConfigurationException.STOREFRONT_PASSWORD_REQUIRED) - } - - @Test - fun `should ignore unsupported error payloads`() { - val eventString = """| - |{ - | "name":"error", - | "body": "[{ - | \"group\": \"authentication\", - | \"reason\": \"invalid signature\", - | \"code\": \"invalid_signature\" - | }]" - |} - | - """.trimMargin() - - checkoutBridge.postMessage(eventString) - - verifyNoInteractions(mockListener) - } - - @Test - fun `should call onCheckoutViewFailedWithError if message cannot be decoded`() { - val eventString = """| - |{ - | "name":"error - |} - | - """.trimMargin() - - checkoutBridge.postMessage(eventString) - - val captor = argumentCaptor() - verify(mockListener).onCheckoutViewFailedWithError(captor.capture()) - - val error = captor.firstValue - assertThat(error).isInstanceOf(CheckoutKitException::class.java) - assertThat(error.message).isEqualTo("Error decoding message from checkout.") - assertThat(error.errorCode).isEqualTo(CheckoutKitException.ERROR_RECEIVING_MESSAGE_FROM_CHECKOUT) - } -} diff --git a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutCompletedEventDecoderTest.kt b/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutCompletedEventDecoderTest.kt deleted file mode 100644 index 36eed240..00000000 --- a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutCompletedEventDecoderTest.kt +++ /dev/null @@ -1,339 +0,0 @@ -/* - * MIT License - * - * Copyright 2023-present, Shopify Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -package com.shopify.checkoutkit - -import com.shopify.checkoutkit.lifecycleevents.Address -import com.shopify.checkoutkit.lifecycleevents.CartLine -import com.shopify.checkoutkit.lifecycleevents.CartLineImage -import com.shopify.checkoutkit.lifecycleevents.CheckoutCompletedEventDecoder -import com.shopify.checkoutkit.lifecycleevents.DeliveryDetails -import com.shopify.checkoutkit.lifecycleevents.DeliveryInfo -import com.shopify.checkoutkit.lifecycleevents.MoneyV2 -import com.shopify.checkoutkit.lifecycleevents.PaymentMethod -import com.shopify.checkoutkit.lifecycleevents.Price -import kotlinx.serialization.json.Json -import org.assertj.core.api.Assertions.assertThat -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mockito.mock -import org.mockito.junit.MockitoJUnitRunner - -@RunWith(MockitoJUnitRunner::class) -class CheckoutCompletedEventDecoderTest { - - private val mockLogWrapper = mock() - - private val decoder = CheckoutCompletedEventDecoder( - decoder = Json { ignoreUnknownKeys = true }, - log = mockLogWrapper - ) - - @Test - fun `should decode completion event order id`() { - val result = decoder.decode(EXAMPLE_EVENT.toWebToSdkEvent()) - val orderDetails = result.orderDetails - - assertThat(orderDetails.id).isEqualTo("gid://shopify/OrderIdentity/9697125302294") - } - - @Test - fun `should decode completion event order cart lines`() { - val result = decoder.decode(EXAMPLE_EVENT.toWebToSdkEvent()) - val orderDetails = result.orderDetails - - assertThat(orderDetails.cart.lines).isEqualTo( - listOf( - CartLine( - image = CartLineImage( - sm = "https://cdn.shopify.com/s/files/1/0692/3996/3670/files/41bc5767-d56f-432c-ac5f-6b9eeee3ba0e.truncated...", - md = "https://cdn.shopify.com/s/files/1/0692/3996/3670/files/41bc5767-d56f-432c-ac5f-6b9eeee3ba0e.truncated...", - lg = "https://cdn.shopify.com/s/files/1/0692/3996/3670/files/41bc5767-d56f-432c-ac5f-6b9eeee3ba0e.truncated...", - altText = null, - ), - quantity = 1, - title = "The Box: How the Shipping Container Made the World Smaller and the World Economy Bigger", - price = MoneyV2( - amount = 8.0, - currencyCode = "GBP", - ), - merchandiseId = "gid://shopify/ProductVariant/43835075002390", - productId = "gid://shopify/Product/8013997834262" - ) - ) - ) - } - - @Test - fun `should decode completion event order price`() { - val result = decoder.decode(EXAMPLE_EVENT.toWebToSdkEvent()) - val orderDetails = result.orderDetails - - assertThat(orderDetails.cart.price).isEqualTo( - Price( - total = MoneyV2( - amount = 13.99, - currencyCode = "GBP", - ), - subtotal = MoneyV2( - amount = 8.0, - currencyCode = "GBP", - ), - taxes = MoneyV2( - amount = 0.0, - currencyCode = "GBP", - ), - shipping = MoneyV2( - amount = 5.99, - currencyCode = "GBP", - ), - discounts = emptyList(), - ) - ) - } - - @Test - fun `should decode completion event email`() { - val result = decoder.decode(EXAMPLE_EVENT.toWebToSdkEvent()) - val orderDetails = result.orderDetails - - assertThat(orderDetails.email).isEqualTo("a.user@shopify.com") - } - - @Test - fun `should decode completion event billing address`() { - val result = decoder.decode(EXAMPLE_EVENT.toWebToSdkEvent()) - val orderDetails = result.orderDetails - - assertThat(orderDetails.billingAddress).isEqualTo( - Address( - city = "Swansea", - countryCode = "GB", - postalCode = "SA1 1AB", - address1 = "100 Street Avenue", - firstName = "Andrew", - lastName = "Person", - zoneCode = "WLS", - phone = "+447915123456", - ) - ) - } - - @Test - fun `should decode completion event payment methods`() { - val result = decoder.decode(EXAMPLE_EVENT.toWebToSdkEvent()) - val orderDetails = result.orderDetails - - assertThat(orderDetails.paymentMethods).isEqualTo( - listOf( - PaymentMethod( - type = "wallet", - details = mapOf( - "amount" to "13.99", - "currency" to "GBP", - "name" to "SHOP_PAY", - ) - ) - ) - ) - } - - @Test - fun `should decode completion event deliveries`() { - val result = decoder.decode(EXAMPLE_EVENT.toWebToSdkEvent()) - val orderDetails = result.orderDetails - - assertThat(orderDetails.deliveries).isEqualTo( - listOf( - DeliveryInfo( - method = "SHIPPING", - details = DeliveryDetails( - location = Address( - city = "Swansea", - countryCode = "GB", - postalCode = "SA1 1AB", - address1 = "100 Street Avenue", - name = "Andrew", - firstName = "Andrew", - lastName = "Person", - zoneCode = "WLS", - phone = "+447915123456", - ) - ) - ) - ) - ) - } - - private fun String.toWebToSdkEvent(): WebToSdkEvent { - return WebToSdkEvent( - name = "completed", - body = this, - ) - } - - companion object { - private val EXAMPLE_EVENT = """ - { - "flowType": "regular", - "orderDetails": { - "id": "gid://shopify/OrderIdentity/9697125302294", - "cart": { - "token": "123", - "lines": [ - { - "image": { - "sm": "https://cdn.shopify.com/s/files/1/0692/3996/3670/files/41bc5767-d56f-432c-ac5f-6b9eeee3ba0e.truncated...", - "md": "https://cdn.shopify.com/s/files/1/0692/3996/3670/files/41bc5767-d56f-432c-ac5f-6b9eeee3ba0e.truncated...", - "lg": "https://cdn.shopify.com/s/files/1/0692/3996/3670/files/41bc5767-d56f-432c-ac5f-6b9eeee3ba0e.truncated..." - }, - "quantity": 1, - "title": "The Box: How the Shipping Container Made the World Smaller and the World Economy Bigger", - "price": { - "amount": 8, - "currencyCode": "GBP" - }, - "merchandiseId": "gid://shopify/ProductVariant/43835075002390", - "productId": "gid://shopify/Product/8013997834262" - } - ], - "price": { - "total": { - "amount": 13.99, - "currencyCode": "GBP" - }, - "subtotal": { - "amount": 8, - "currencyCode": "GBP" - }, - "taxes": { - "amount": 0, - "currencyCode": "GBP" - }, - "shipping": { - "amount": 5.99, - "currencyCode": "GBP" - } - } - }, - "email": "a.user@shopify.com", - "shippingAddress": { - "city": "Swansea", - "countryCode": "GB", - "postalCode": "SA1 1AB", - "address1": "100 Street Avenue", - "firstName": "Andrew", - "lastName": "Person", - "name": "Andrew", - "zoneCode": "WLS", - "phone": "+447915123456", - "coordinates": { - "latitude": 54.5936785, - "longitude": -3.013167399999999 - } - }, - "billingAddress": { - "city": "Swansea", - "countryCode": "GB", - "postalCode": "SA1 1AB", - "address1": "100 Street Avenue", - "firstName": "Andrew", - "lastName": "Person", - "zoneCode": "WLS", - "phone": "+447915123456" - }, - "paymentMethods": [ - { - "type": "wallet", - "details": { - "amount": "13.99", - "currency": "GBP", - "name": "SHOP_PAY" - } - } - ], - "deliveries": [ - { - "method": "SHIPPING", - "details": { - "location": { - "city": "Swansea", - "countryCode": "GB", - "postalCode": "SA1 1AB", - "address1": "100 Street Avenue", - "firstName": "Andrew", - "lastName": "Person", - "name": "Andrew", - "zoneCode": "WLS", - "phone": "+447915123456", - "coordinates": { - "latitude": 54.5936785, - "longitude": -3.013167399999999 - } - } - } - } - ] - }, - "orderId": "gid://shopify/OrderIdentity/9697125302294", - "cart": { - "lines": [ - { - "image": { - "sm": "https://cdn.shopify.com/s/files/1/0692/3996/3670/files/41bc5767-d56f-432c-ac5f-6b9eeee3ba0e.__CR0_0_300_300_PT0_SX300_V1_64x64.jpg?v=1689689735", - "md": "https://cdn.shopify.com/s/files/1/0692/3996/3670/files/41bc5767-d56f-432c-ac5f-6b9eeee3ba0e.__CR0_0_300_300_PT0_SX300_V1_128x128.jpg?v=1689689735", - "lg": "https://cdn.shopify.com/s/files/1/0692/3996/3670/files/41bc5767-d56f-432c-ac5f-6b9eeee3ba0e.__CR0_0_300_300_PT0_SX300_V1_256x256.jpg?v=1689689735" - }, - "quantity": 1, - "title": "The Box: How the Shipping Container Made the World Smaller and the World Economy Bigger", - "price": { - "amount": 8, - "currencyCode": "GBP" - }, - "merchandiseId": "gid://shopify/ProductVariant/43835075002390", - "productId": "gid://shopify/Product/8013997834262" - } - ], - "price": { - "total": { - "amount": 13.99, - "currencyCode": "GBP" - }, - "subtotal": { - "amount": 8, - "currencyCode": "GBP" - }, - "taxes": { - "amount": 0, - "currencyCode": "CAD" - }, - "shipping": { - "amount": 5.99, - "currencyCode": "GBP" - } - } - } - } - """.trimIndent() - } -} diff --git a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutWebViewTest.kt b/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutWebViewTest.kt index cb901079..a9d3413c 100644 --- a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutWebViewTest.kt +++ b/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutWebViewTest.kt @@ -70,8 +70,8 @@ class CheckoutWebViewTest { assertThat(view.id).isNotNull assertThat(shadowOf(view).webViewClient.javaClass).isEqualTo(CheckoutWebView.CheckoutWebViewClient::class.java) assertThat(shadowOf(view).backgroundColor).isEqualTo(Color.TRANSPARENT) - assertThat(shadowOf(view).getJavascriptInterface("android").javaClass) - .isEqualTo(CheckoutBridge::class.java) + assertThat(shadowOf(view).getJavascriptInterface(EmbeddedCheckoutProtocol.INTERFACE_NAME).javaClass) + .isEqualTo(EmbeddedCheckoutProtocol::class.java) } @Test @@ -111,8 +111,8 @@ class CheckoutWebViewTest { val shadow = shadowOf(view) shadow.callOnAttachedToWindow() - assertThat(shadow.getJavascriptInterface("android").javaClass) - .isEqualTo(CheckoutBridge::class.java) + assertThat(shadow.getJavascriptInterface(EmbeddedCheckoutProtocol.INTERFACE_NAME).javaClass) + .isEqualTo(EmbeddedCheckoutProtocol::class.java) } @Test @@ -122,7 +122,7 @@ class CheckoutWebViewTest { val shadow = shadowOf(view) shadow.callOnDetachedFromWindow() - assertThat(shadow.getJavascriptInterface("android")).isNull() + assertThat(shadow.getJavascriptInterface(EmbeddedCheckoutProtocol.INTERFACE_NAME)).isNull() } @Test diff --git a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/InteropTest.java b/platforms/android/lib/src/test/java/com/shopify/checkoutkit/InteropTest.java index 8d91a079..c3d8e9ad 100644 --- a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/InteropTest.java +++ b/platforms/android/lib/src/test/java/com/shopify/checkoutkit/InteropTest.java @@ -5,10 +5,6 @@ import androidx.activity.ComponentActivity; import androidx.annotation.NonNull; -import com.shopify.checkoutkit.errorevents.CheckoutErrorDecoder; -import com.shopify.checkoutkit.lifecycleevents.CheckoutCompletedEvent; -import com.shopify.checkoutkit.lifecycleevents.CheckoutCompletedEventDecoder; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -18,112 +14,8 @@ import org.robolectric.android.controller.ActivityController; import org.robolectric.shadows.ShadowDialog; -import kotlinx.serialization.json.Json; -import kotlinx.serialization.json.JsonKt; - @RunWith(RobolectricTestRunner.class) public class InteropTest { - private final String EXAMPLE_EVENT = "{\n" + - " \"orderDetails\": {\n" + - " \"id\": \"gid://shopify/OrderIdentity/9697125302294\",\n" + - " \"cart\": {\n" + - " \"token\": \"123abc\",\n" + - " \"lines\": [\n" + - " {\n" + - " \"image\": {\n" + - " \"sm\": \"https://cdn.shopify.com/s/files/1/0692/3996/3670/files/41bc5767-d56f-432c-ac5f-6b9eeee3ba0e.truncated...\",\n" + - " \"md\": \"https://cdn.shopify.com/s/files/1/0692/3996/3670/files/41bc5767-d56f-432c-ac5f-6b9eeee3ba0e.truncated...\",\n" + - " \"lg\": \"https://cdn.shopify.com/s/files/1/0692/3996/3670/files/41bc5767-d56f-432c-ac5f-6b9eeee3ba0e.truncated...\"\n" + - " },\n" + - " \"quantity\": 1,\n" + - " \"title\": \"The Box: How the Shipping Container Made the World Smaller and the World Economy Bigger\",\n" + - " \"price\": {\n" + - " \"amount\": 8,\n" + - " \"currencyCode\": \"GBP\"\n" + - " },\n" + - " \"merchandiseId\": \"gid://shopify/ProductVariant/43835075002390\",\n" + - " \"productId\": \"gid://shopify/Product/8013997834262\"\n" + - " }\n" + - " ],\n" + - " \"price\": {\n" + - " \"total\": {\n" + - " \"amount\": 13.99,\n" + - " \"currencyCode\": \"GBP\"\n" + - " },\n" + - " \"subtotal\": {\n" + - " \"amount\": 8,\n" + - " \"currencyCode\": \"GBP\"\n" + - " },\n" + - " \"taxes\": {\n" + - " \"amount\": 0,\n" + - " \"currencyCode\": \"GBP\"\n" + - " },\n" + - " \"shipping\": {\n" + - " \"amount\": 5.99,\n" + - " \"currencyCode\": \"GBP\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"email\": \"a.user@shopify.com\",\n" + - " \"shippingAddress\": {\n" + - " \"city\": \"Swansea\",\n" + - " \"countryCode\": \"GB\",\n" + - " \"postalCode\": \"SA1 1AB\",\n" + - " \"address1\": \"100 Street Avenue\",\n" + - " \"firstName\": \"Andrew\",\n" + - " \"lastName\": \"Person\",\n" + - " \"name\": \"Andrew\",\n" + - " \"zoneCode\": \"WLS\",\n" + - " \"phone\": \"+447915123456\",\n" + - " \"coordinates\": {\n" + - " \"latitude\": 54.5936785,\n" + - " \"longitude\": -3.013167399999999\n" + - " }\n" + - " },\n" + - " \"billingAddress\": {\n" + - " \"city\": \"Swansea\",\n" + - " \"countryCode\": \"GB\",\n" + - " \"postalCode\": \"SA1 1AB\",\n" + - " \"address1\": \"100 Street Avenue\",\n" + - " \"firstName\": \"Andrew\",\n" + - " \"lastName\": \"Person\",\n" + - " \"zoneCode\": \"WLS\",\n" + - " \"phone\": \"+447915123456\"\n" + - " },\n" + - " \"paymentMethods\": [\n" + - " {\n" + - " \"type\": \"wallet\",\n" + - " \"details\": {\n" + - " \"amount\": \"13.99\",\n" + - " \"currency\": \"GBP\",\n" + - " \"name\": \"SHOP_PAY\"\n" + - " }\n" + - " }\n" + - " ],\n" + - " \"deliveries\": [\n" + - " {\n" + - " \"method\": \"SHIPPING\",\n" + - " \"details\": {\n" + - " \"location\": {\n" + - " \"city\": \"Swansea\",\n" + - " \"countryCode\": \"GB\",\n" + - " \"postalCode\": \"SA1 1AB\",\n" + - " \"address1\": \"100 Street Avenue\",\n" + - " \"firstName\": \"Andrew\",\n" + - " \"lastName\": \"Person\",\n" + - " \"name\": \"Andrew\",\n" + - " \"zoneCode\": \"WLS\",\n" + - " \"phone\": \"+447915123456\",\n" + - " \"coordinates\": {\n" + - " \"latitude\": 54.5936785,\n" + - " \"longitude\": -3.013167399999999\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - " ]\n" + - " }\n" + - " }"; private Configuration initialConfiguration = null; @Before @@ -155,47 +47,6 @@ public void onCheckoutCanceled() { assertThat(listener).isNotNull(); } - @SuppressWarnings("all") - @Test - public void canAccessFieldsOnExceptions() { - String eventString = "[{" + - "\"group\": \"expired\"," + - "\"reason\": \"Checkout has expired\"," + - "\"code\": \"cart_completed\"" + - "}]"; - - WebToSdkEvent webEvent = new WebToSdkEvent("error", eventString); - Json json = JsonKt.Json(Json.Default, b -> { - b.setIgnoreUnknownKeys(true); - return null; - }); - CheckoutErrorDecoder decoder = new CheckoutErrorDecoder(json); - - CheckoutException exception = decoder.decode(webEvent); - - assertThat(exception.getClass()).isEqualTo(CheckoutExpiredException.class); - assertThat(exception.getErrorCode()).isEqualTo("cart_completed"); - assertThat(exception.getErrorDescription()).isEqualTo("Checkout has expired"); - } - - @SuppressWarnings("all") - @Test - public void canAccessFieldsOnCheckoutCompletedEvent() { - WebToSdkEvent webEvent = new WebToSdkEvent("completed", EXAMPLE_EVENT); - Json json = JsonKt.Json(Json.Default, b -> { - b.setIgnoreUnknownKeys(true); - return null; - }); - CheckoutCompletedEventDecoder decoder = new CheckoutCompletedEventDecoder(json); - - CheckoutCompletedEvent event = decoder.decode(webEvent); - - assertThat(event.getOrderDetails().getId()) - .isEqualTo("gid://shopify/OrderIdentity/9697125302294"); - assertThat(event.getOrderDetails().getCart().getLines().get(0).getPrice().getAmount()) - .isEqualTo(8.0); - } - @Test public void canConfigureCheckoutKit() { ShopifyCheckoutKit.configure(configuration -> { diff --git a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/errors/CheckoutErrorDecoderTest.kt b/platforms/android/lib/src/test/java/com/shopify/checkoutkit/errors/CheckoutErrorDecoderTest.kt deleted file mode 100644 index 52764255..00000000 --- a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/errors/CheckoutErrorDecoderTest.kt +++ /dev/null @@ -1,166 +0,0 @@ -/* - * MIT License - * - * Copyright 2023-present, Shopify Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.shopify.checkoutkit.errors - -import com.shopify.checkoutkit.ClientException -import com.shopify.checkoutkit.LogWrapper -import com.shopify.checkoutkit.WebToSdkEvent -import com.shopify.checkoutkit.errorevents.CheckoutErrorDecoder -import com.shopify.checkoutkit.errorevents.CheckoutErrorGroup -import com.shopify.checkoutkit.errorevents.CheckoutErrorPayload -import kotlinx.serialization.json.Json -import org.assertj.core.api.Assertions.assertThat -import org.junit.Assert.assertThrows -import org.junit.Test -import org.mockito.Mockito - -class CheckoutErrorDecoderTest { - - private val logWrapper = Mockito.mock() - private val decoder = CheckoutErrorDecoder(Json { ignoreUnknownKeys = true }, logWrapper) - - @Test - fun `should decode a checkout error`() { - val event = WebToSdkEvent( - name = "error", - body = """[ - |{ - | "group": "unrecoverable", - | "flowType": "regular", - | "type": "sdk_not_enabled", - | "code": "sdk_not_enabled", - | "reason": "" - |} - ] - """.trimMargin() - ) - - val decoded = decoder.decodeMessage(event) - - assertThat(decoded).isEqualTo( - CheckoutErrorPayload( - group = CheckoutErrorGroup.UNRECOVERABLE, - flowType = "regular", - type = "sdk_not_enabled", - code = "sdk_not_enabled", - reason = "" - ) - ) - } - - @Test - fun `should return group = unsupported for any groups that arent supported`() { - val event = WebToSdkEvent( - name = "error", - body = """[ - |{ - | "group": "other", - | "flowType": "regular", - | "type": "invalid_signature", - | "code": "invalid_signature", - | "reason": "" - |} - ] - """.trimMargin() - ) - - val decoded = decoder.decodeMessage(event) - - assertThat(decoded).isEqualTo( - CheckoutErrorPayload( - group = CheckoutErrorGroup.UNSUPPORTED, - flowType = "regular", - type = "invalid_signature", - code = "invalid_signature", - reason = "" - ) - ) - } - - @Test - fun `should throw if decoding fails`() { - val event = WebToSdkEvent( - name = "error", - body = """[ - |{ - | "group": "unrecoverable", - | "flowType": "regular", - | "type": "invalid_ - |} - ] - """.trimMargin() - ) - - assertThrows(RuntimeException::class.java) { decoder.decodeMessage(event) } - } - - @Test - fun `should decode unrecoverable error as client exception`() { - val event = WebToSdkEvent( - name = "error", - body = """[ - |{ - | "group": "unrecoverable", - | "flowType": "regular", - | "type": "sdk_not_enabled", - | "code": "sdk_not_enabled", - | "reason": "SDK not enabled" - |} - ] - """.trimMargin() - ) - - val decoded = decoder.decode(event) - - assertThat(decoded).isInstanceOf(ClientException::class.java) - assertThat(decoded!!.errorDescription).isEqualTo("SDK not enabled") - } - - @Test - fun `should return first message if multiple exist in payload`() { - val event = WebToSdkEvent( - name = "error", - body = """[ - |{ - | "group": "unrecoverable", - | "flowType": "regular", - | "type": "sdk_not_enabled", - | "code": "sdk_not_enabled", - | "reason": "" - |}, - |{ - | "group": "unrecoverable", - | "flowType": "regular", - | "type": "invalid_checkout_url", - | "code": "invalid_checkout_url", - | "reason": "" - |} - ] - """.trimMargin() - ) - - val decoded = decoder.decodeMessage(event) - - assertThat(decoded.code).isEqualTo("sdk_not_enabled") - } -}