diff --git a/platforms/android/AGENTS.md b/platforms/android/AGENTS.md index c55c7825..307a18a6 100644 --- a/platforms/android/AGENTS.md +++ b/platforms/android/AGENTS.md @@ -34,15 +34,15 @@ The sample is a separate Gradle composite (`samples/MobileBuyIntegration/setting - Tests use **Robolectric** (`@RunWith(RobolectricTestRunner::class)`) to exercise Android framework code without a device. - Main-thread tasks are drained with `shadowOf(Looper.getMainLooper()).runToEndOfTasks()`. If a test involves posted work and seems flaky, check whether this is being called. -- Assertion library is **AssertJ**; mocking is **Mockito** + **Mockito-Kotlin**. Don't introduce new assertion/mocking libraries without discussion. -- Mockito is pinned at **4.x** intentionally — Mockito 5.x requires JVM target 11, and the library is on 1.8. Noted in `lib/build.gradle` with `// noinspection NewerVersionAvailable` comments. +- Assertion library is **AssertJ**; mocking is **Mockito** + **Mockito-Kotlin**. Mockito is on 5.x because the library targets JVM 11. Don't introduce new assertion/mocking libraries without discussion. - Tests live in the same package as the class under test (file name: `ClassNameTest.kt`). ## Conventions - **`-Xexplicit-api=strict`** is on (`lib/build.gradle`). Every public class, method, field, and property must have an explicit visibility modifier. "Accidentally public" is not a thing here. This is a consumer-protection rule — if you see a public-by-default declaration, it was deliberate. - **Max line length: 140** (detekt-enforced). Detekt config: `lib/detekt.config.yml`. -- **Library JVM target: 1.8.** Intentional for consumer compatibility; don't raise without a major-version discussion. +- **MIT license header required on every new source file.** Format: copy the top comment of any existing `.kt` or `.java` file in `lib/src/main` or `lib/src/test`. Enforced in CI via the repo-root `scripts/check_license_headers.rb`. +- **Library JVM target: 11.** Consumers must build with JDK 11+ to consume the AAR. Raising further is a major-version discussion. - **Library Kotlin `apiVersion` / `languageVersion` are pinned at 2.0.** Set in `lib/build.gradle` so the AAR's bytecode stays consumable by Kotlin 2.0+ projects even though the compiler itself is on a newer 2.x. Bumping this pin is the consumer-facing breaking change, not bumping the compiler - treat it as a planned major-version event. - **Prefer generated protocol models.** Before adding hand-written protocol DTOs, check the generated models in `lib/src/main/java/com/shopify/checkoutkit/Models.kt` and the OpenRPC schema. Use generated UCP/ECP types for wire payloads; reserve local DTOs for Android-internal transport helpers that are not represented in the schema. diff --git a/platforms/android/lib/api/lib.api b/platforms/android/lib/api/lib.api index 92379a6b..9f7b4794 100644 --- a/platforms/android/lib/api/lib.api +++ b/platforms/android/lib/api/lib.api @@ -1091,8 +1091,6 @@ public final class com/shopify/checkoutkit/Configuration { public final fun component1 ()Lcom/shopify/checkoutkit/ColorScheme; public final fun component2 ()Lcom/shopify/checkoutkit/Platform; public final fun component3 ()Lcom/shopify/checkoutkit/LogLevel; - public final fun copy (Lcom/shopify/checkoutkit/ColorScheme;Lcom/shopify/checkoutkit/Platform;Lcom/shopify/checkoutkit/LogLevel;)Lcom/shopify/checkoutkit/Configuration; - public static synthetic fun copy$default (Lcom/shopify/checkoutkit/Configuration;Lcom/shopify/checkoutkit/ColorScheme;Lcom/shopify/checkoutkit/Platform;Lcom/shopify/checkoutkit/LogLevel;ILjava/lang/Object;)Lcom/shopify/checkoutkit/Configuration; public fun equals (Ljava/lang/Object;)Z public final fun getColorScheme ()Lcom/shopify/checkoutkit/ColorScheme; public final fun getLogLevel ()Lcom/shopify/checkoutkit/LogLevel; diff --git a/platforms/android/lib/build.gradle b/platforms/android/lib/build.gradle index 4b31878b..49150d83 100644 --- a/platforms/android/lib/build.gradle +++ b/platforms/android/lib/build.gradle @@ -24,8 +24,8 @@ ext { junit_version = '4.13.2' robolectric_version = '4.16.1' - mockito_core_version = '4.11.0' - mockito_kotlin_version = '4.1.0' + mockito_core_version = '5.23.0' + mockito_kotlin_version = '5.4.0' assertj_version = '3.27.7' awaitility_version = '4.3.0' detekt_formatting_version = '1.23.8' @@ -63,8 +63,8 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } testOptions { unitTests.includeAndroidResources = true @@ -89,7 +89,7 @@ android { tasks.withType(KotlinJvmCompile).configureEach { compilerOptions { - jvmTarget.set(JvmTarget.JVM_1_8) + jvmTarget.set(JvmTarget.JVM_11) // Pin language/API version so bytecode stays consumable by Kotlin 2.0+ consumers // even though the compiler is on a newer 2.x. Kotlin 1.9 is deprecated by the 2.x // compiler, so 2.0 is the lowest pin we can hold without taking deprecation warnings; @@ -108,11 +108,8 @@ dependencies { testImplementation "junit:junit:$junit_version" testImplementation "org.robolectric:robolectric:$robolectric_version" - // noinspection NewerVersionAvailable -- mockito 5 requires jvm target 1.11 testImplementation "org.mockito:mockito-core:$mockito_core_version" - // noinspection NewerVersionAvailable -- mockito 5 requires jvm target 1.11 testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version" - // noinspection NewerVersionAvailable -- mockito 5 requires jvm target 1.11 testImplementation "org.mockito:mockito-android:$mockito_core_version" testImplementation "org.assertj:assertj-core:$assertj_version" testImplementation "org.awaitility:awaitility:$awaitility_version" diff --git a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/Configuration.kt b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/Configuration.kt index 5955ebd0..ac9a99d4 100644 --- a/platforms/android/lib/src/main/java/com/shopify/checkoutkit/Configuration.kt +++ b/platforms/android/lib/src/main/java/com/shopify/checkoutkit/Configuration.kt @@ -5,6 +5,7 @@ package com.shopify.checkoutkit * * Allows specifying the colorScheme that should be used for checkout. */ +@ConsistentCopyVisibility public data class Configuration internal constructor( var colorScheme: ColorScheme = ColorScheme.Automatic(), var platform: Platform? = null, diff --git a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutDialogTest.kt b/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutDialogTest.kt index 9a386818..f626ee04 100644 --- a/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutDialogTest.kt +++ b/platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutDialogTest.kt @@ -348,7 +348,9 @@ class CheckoutDialogTest { val dialog = ShadowDialog.getLatestDialog() as CheckoutDialog val webView = dialog.currentWebView() webView.loadUrl("https://shopify.com/checkouts/c/abc/step2") - shadowOf(webView).setCanGoBack(true) + // ShadowWebView doesn't auto-track loadUrl in history; push two entries so canGoBack() returns true. + shadowOf(webView).pushEntryToHistory("https://shopify.com/checkouts/c/abc") + shadowOf(webView).pushEntryToHistory("https://shopify.com/checkouts/c/abc/step2") shadowOf(Looper.getMainLooper()).runToEndOfTasks() dialog.onBackPressedDispatcher.onBackPressed() @@ -368,7 +370,8 @@ class CheckoutDialogTest { val dialog = ShadowDialog.getLatestDialog() as CheckoutDialog val webView = dialog.currentWebView() webView.loadUrl("https://shopify.com/cn-12345/thank-you") - shadowOf(webView).setCanGoBack(true) + shadowOf(webView).pushEntryToHistory("https://shopify.com/checkouts/c/abc") + shadowOf(webView).pushEntryToHistory("https://shopify.com/cn-12345/thank-you") shadowOf(Looper.getMainLooper()).runToEndOfTasks() dialog.onBackPressedDispatcher.onBackPressed()