Skip to content

Commit

Permalink
Merge pull request #10 from Shopify/dk/remove-println
Browse files Browse the repository at this point in the history
add tests for default checkout event processor
  • Loading branch information
kiftio authored Nov 23, 2023
2 parents de18099 + 63fbced commit c096f73
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,17 @@ internal class NoopEventProcessor : CheckoutEventProcessor {
* for handling checkout events and interacting with the Android operating system.
* @param context from which we will launch intents.
*/
public abstract class DefaultCheckoutEventProcessor(private val context: Context) : CheckoutEventProcessor {
public abstract class DefaultCheckoutEventProcessor(
private val context: Context,
private val log: LogWrapper = LogWrapper(),
) : CheckoutEventProcessor {

override fun onCheckoutLinkClicked(uri: Uri) {
when (uri.scheme) {
"tel" -> context.launchPhoneApp(uri.schemeSpecificPart)
"mailto" -> context.launchEmailApp(uri.schemeSpecificPart)
"https", "http" -> context.launchBrowser(uri)
else -> println("Unrecognized scheme for uri $uri")
else -> log.w(TAG, "Unrecognized scheme for link clicked in checkout '$uri'")
}
}

Expand All @@ -142,4 +145,8 @@ public abstract class DefaultCheckoutEventProcessor(private val context: Context
val intent = Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phone, null))
startActivity(intent)
}

private companion object {
private const val TAG = "DefaultCheckoutEventProcessor"
}
}
38 changes: 38 additions & 0 deletions lib/src/main/java/com/shopify/checkoutkit/LogWrapper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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.util.Log

/**
* Wrap Log class static methods to allow testing
*/
public class LogWrapper {
public fun w(tag: String, msg: String) {
Log.w(tag, msg)
}

public fun e(tag: String, msg: String) {
Log.e(tag, msg)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* 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.content.Intent
import android.net.Uri
import androidx.activity.ComponentActivity
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows.shadowOf
import org.robolectric.shadows.ShadowActivity

@RunWith(RobolectricTestRunner::class)
class DefaultCheckoutEventProcessorTest {

private lateinit var activity: ComponentActivity
private lateinit var shadowActivity: ShadowActivity

@Before
fun setUp() {
activity = Robolectric.buildActivity(ComponentActivity::class.java).get()
shadowActivity = shadowOf(activity)
}

@Test
fun `onCheckoutLinkClicked with http scheme launches action view intent with uri as data`() {
val processor = processor(activity)
val uri = Uri.parse("https://shopify.com")

processor.onCheckoutLinkClicked(uri)

val intent = shadowActivity.peekNextStartedActivityForResult().intent
assertThat(intent.data).isEqualTo(uri)
intent.type = Intent.ACTION_VIEW
}

@Test
fun `onCheckoutLinkClicked with mailto scheme launches email intent with to address`() {
val processor = processor(activity)
val uri = Uri.parse("mailto:test.user@shopify.com")

processor.onCheckoutLinkClicked(uri)

val intent = shadowActivity.peekNextStartedActivityForResult().intent
assertThat(intent.getStringArrayExtra(Intent.EXTRA_EMAIL)).isEqualTo(arrayOf("test.user@shopify.com"))
intent.type = "vnd.android.cursor.item/email"
}

@Test
fun `onCheckoutLinkClicked with tel scheme launches action dial intent with phone number`() {
val processor = processor(activity)
val uri = Uri.parse("tel:0123456789")

processor.onCheckoutLinkClicked(uri)

val intent = shadowActivity.peekNextStartedActivityForResult().intent
assertThat(intent.data).isEqualTo(uri)
intent.type = Intent.ACTION_DIAL
}

@Test
fun `onCheckoutLinkedClick with unhandled scheme logs warning`() {
val log = mock<LogWrapper>()
val processor = object: DefaultCheckoutEventProcessor(activity, log) {
override fun onCheckoutCompleted() {/* not implemented */}
override fun onCheckoutFailed(error: CheckoutException) {/* not implemented */}
override fun onCheckoutCanceled() {/* not implemented */}
}

val uri = Uri.parse("ftp:lsklsm")

processor.onCheckoutLinkClicked(uri)

assertThat(shadowActivity.peekNextStartedActivityForResult()).isNull()
verify(log).w("DefaultCheckoutEventProcessor", "Unrecognized scheme for link clicked in checkout 'ftp:lsklsm'")
}

private fun processor(activity: ComponentActivity): DefaultCheckoutEventProcessor {
return object: DefaultCheckoutEventProcessor(activity) {
override fun onCheckoutCompleted() {/* not implemented */}
override fun onCheckoutFailed(error: CheckoutException) {/* not implemented */}
override fun onCheckoutCanceled() {/* not implemented */}
}
}
}

0 comments on commit c096f73

Please sign in to comment.