Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,7 @@ internal class CheckoutWebView(context: Context, attributeSet: AttributeSet? = n
log.d(LOG_TAG, "Loading checkout with url $url. IsPreload: $isPreload.")
this.isPreload = isPreload
Handler(Looper.getMainLooper()).post {
val ecpUrl = url.appendEcpParams(
specVersion = CheckoutProtocol.specVersion,
colorScheme = ShopifyCheckoutKit.configuration.colorScheme,
Comment thread
toneymathews marked this conversation as resolved.
)
val ecpUrl = url.appendEcpParams(specVersion = CheckoutProtocol.specVersion)
val headers = if (isPreload) mutableMapOf("Shopify-Purpose" to "prefetch") else mutableMapOf()
loadUrl(ecpUrl, headers)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,33 +40,23 @@ internal fun String.isOneTimeUse(): Boolean = this.contains("multipass")
* params already present on the URL untouched. Idempotent on re-call.
*
* - `ec_version` — the ECP spec version the SDK speaks
* - `ec_color_scheme` — emitted only when [colorScheme] is [ColorScheme.Light] or [ColorScheme.Dark]
* - `ec_delegate` — fixed to `window.open` so checkout delegates link opens to the bridge
*/
internal fun String.appendEcpParams(specVersion: String, colorScheme: ColorScheme): String {
internal fun String.appendEcpParams(specVersion: String): String {
val uri = this.toUri()
val builder = uri.buildUpon()
if (uri.getQueryParameter(EC_VERSION_PARAM) == null) {
builder.appendQueryParameter(EC_VERSION_PARAM, specVersion)
}
if (uri.getQueryParameter(EC_COLOR_SCHEME_PARAM) == null) {
colorScheme.ecParamValue()?.let { builder.appendQueryParameter(EC_COLOR_SCHEME_PARAM, it) }
}
if (uri.getQueryParameter(EC_DELEGATE_PARAM) == null) {
builder.appendQueryParameter(EC_DELEGATE_PARAM, EC_DELEGATE_VALUE)
}
return builder.build().toString()
}

private fun ColorScheme.ecParamValue(): String? = when (this) {
is ColorScheme.Light, is ColorScheme.Dark -> this.id
else -> null
}

private val CONFIRMATION_PATH_REGEX = Regex(pattern = "^(thank[-_]+you)$", option = RegexOption.IGNORE_CASE)

private const val EC_VERSION_PARAM = "ec_version"
private const val EC_COLOR_SCHEME_PARAM = "ec_color_scheme"
private const val EC_DELEGATE_PARAM = "ec_delegate"
private const val EC_DELEGATE_VALUE = "window.open"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ class CheckoutWebViewTest {
@After
fun tearDown() {
ShopifyCheckoutKit.configuration.platform = null
ShopifyCheckoutKit.configuration.colorScheme = ColorScheme.Automatic()
}

private fun loadedUrl(platform: Platform? = null): String {
Expand Down Expand Up @@ -303,58 +302,6 @@ class CheckoutWebViewTest {
assertThat(loadedUrl.split("ec_version").size - 1).isEqualTo(1)
}

@Test
fun `loadCheckout appends ec_color_scheme even when ec_version already present`() {
ShopifyCheckoutKit.configuration.colorScheme = ColorScheme.Light()
val view = CheckoutWebView(activity)
view.loadCheckout("https://checkout.shopify.com/cart/123?ec_version=2026-01-23", false)
ShadowLooper.shadowMainLooper().runToEndOfTasks()

val loadedUrl = shadowOf(view).lastLoadedUrl!!
assertThat(loadedUrl).contains("ec_version=2026-01-23")
assertThat(loadedUrl).contains("ec_color_scheme=light")
}

@Test
fun `loadCheckout appends ec_color_scheme=light for Light color scheme`() {
ShopifyCheckoutKit.configuration.colorScheme = ColorScheme.Light()
val view = CheckoutWebView(activity)
view.loadCheckout("https://checkout.shopify.com/cart/123", false)
ShadowLooper.shadowMainLooper().runToEndOfTasks()

assertThat(shadowOf(view).lastLoadedUrl).contains("ec_color_scheme=light")
}

@Test
fun `loadCheckout appends ec_color_scheme=dark for Dark color scheme`() {
ShopifyCheckoutKit.configuration.colorScheme = ColorScheme.Dark()
val view = CheckoutWebView(activity)
view.loadCheckout("https://checkout.shopify.com/cart/123", false)
ShadowLooper.shadowMainLooper().runToEndOfTasks()

assertThat(shadowOf(view).lastLoadedUrl).contains("ec_color_scheme=dark")
}

@Test
fun `loadCheckout omits ec_color_scheme for Automatic color scheme`() {
ShopifyCheckoutKit.configuration.colorScheme = ColorScheme.Automatic()
val view = CheckoutWebView(activity)
view.loadCheckout("https://checkout.shopify.com/cart/123", false)
ShadowLooper.shadowMainLooper().runToEndOfTasks()

assertThat(shadowOf(view).lastLoadedUrl).doesNotContain("ec_color_scheme")
}

@Test
fun `loadCheckout omits ec_color_scheme for Web color scheme`() {
ShopifyCheckoutKit.configuration.colorScheme = ColorScheme.Web()
val view = CheckoutWebView(activity)
view.loadCheckout("https://checkout.shopify.com/cart/123", false)
ShadowLooper.shadowMainLooper().runToEndOfTasks()

assertThat(shadowOf(view).lastLoadedUrl).doesNotContain("ec_color_scheme")
}

// endregion

// region buildEcpUrl — ec_delegate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,46 +84,24 @@ class UriExtensionsTest {
}

@Test
fun `appendEcpParams adds ec_version, ec_color_scheme=light, and ec_delegate for Light scheme`() {
val result = BASE_URL.appendEcpParams(SPEC_VERSION, ColorScheme.Light()).toUri()
fun `appendEcpParams adds ec_version and ec_delegate`() {
val result = BASE_URL.appendEcpParams(SPEC_VERSION).toUri()
assertThat(result.getQueryParameter("ec_version")).isEqualTo(SPEC_VERSION)
assertThat(result.getQueryParameter("ec_color_scheme")).isEqualTo("light")
assertThat(result.getQueryParameter("ec_delegate")).isEqualTo("window.open")
}

@Test
fun `appendEcpParams emits ec_color_scheme=dark for Dark scheme`() {
val result = BASE_URL.appendEcpParams(SPEC_VERSION, ColorScheme.Dark()).toUri()
assertThat(result.getQueryParameter("ec_color_scheme")).isEqualTo("dark")
}

@Test
fun `appendEcpParams omits ec_color_scheme for Automatic scheme`() {
val result = BASE_URL.appendEcpParams(SPEC_VERSION, ColorScheme.Automatic()).toUri()
assertThat(result.getQueryParameter("ec_color_scheme")).isNull()
assertThat(result.getQueryParameter("ec_version")).isEqualTo(SPEC_VERSION)
assertThat(result.getQueryParameter("ec_delegate")).isEqualTo("window.open")
}

@Test
fun `appendEcpParams omits ec_color_scheme for Web scheme`() {
val result = BASE_URL.appendEcpParams(SPEC_VERSION, ColorScheme.Web()).toUri()
assertThat(result.getQueryParameter("ec_color_scheme")).isNull()
}

@Test
fun `appendEcpParams is idempotent on re-call`() {
val once = BASE_URL.appendEcpParams(SPEC_VERSION, ColorScheme.Light())
val twice = once.appendEcpParams(SPEC_VERSION, ColorScheme.Light()).toUri()
val once = BASE_URL.appendEcpParams(SPEC_VERSION)
val twice = once.appendEcpParams(SPEC_VERSION).toUri()
assertThat(twice.getQueryParameters("ec_version")).hasSize(1)
assertThat(twice.getQueryParameters("ec_color_scheme")).hasSize(1)
assertThat(twice.getQueryParameters("ec_delegate")).hasSize(1)
}

@Test
fun `appendEcpParams preserves existing query parameters`() {
val url = "$BASE_URL?key=cart_token&utm_source=email"
val result = url.appendEcpParams(SPEC_VERSION, ColorScheme.Light()).toUri()
val result = url.appendEcpParams(SPEC_VERSION).toUri()
assertThat(result.getQueryParameter("key")).isEqualTo("cart_token")
assertThat(result.getQueryParameter("utm_source")).isEqualTo("email")
assertThat(result.getQueryParameter("ec_version")).isEqualTo(SPEC_VERSION)
Expand All @@ -132,7 +110,7 @@ class UriExtensionsTest {
@Test
fun `appendEcpParams does not overwrite caller-supplied ECP params`() {
val url = "$BASE_URL?ec_version=override&ec_delegate=custom"
val result = url.appendEcpParams(SPEC_VERSION, ColorScheme.Light()).toUri()
val result = url.appendEcpParams(SPEC_VERSION).toUri()
assertThat(result.getQueryParameter("ec_version")).isEqualTo("override")
assertThat(result.getQueryParameter("ec_delegate")).isEqualTo("custom")
}
Expand Down
Loading