Skip to content

Commit

Permalink
Format
Browse files Browse the repository at this point in the history
  • Loading branch information
AnasNaouchi committed Jun 11, 2024
1 parent 6639c9b commit fff7c99
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import android.app.Activity.RESULT_OK
import android.app.Application
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.WindowManager
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents.intended
Expand All @@ -27,7 +25,6 @@ import co.omise.android.api.Client
import co.omise.android.api.Request
import co.omise.android.api.RequestListener
import co.omise.android.models.Capability
import co.omise.android.models.PaymentMethod
import co.omise.android.models.SourceType
import co.omise.android.models.Token
import co.omise.android.models.TokenizationMethod
Expand All @@ -51,12 +48,14 @@ import org.mockito.kotlin.whenever
class PaymentCreatorActivityTest {
@get:Rule
val intentRule = IntentsRule()
// capabilities requested by the merchant
private val capability = Capability.create(
allowCreditCard = true,
sourceTypes = listOf(SourceType.Fpx(), SourceType.TrueMoney),
tokenizationMethods = listOf(TokenizationMethod.GooglePay)
)

// capabilities requested by the merchant
private val capability =
Capability.create(
allowCreditCard = true,
sourceTypes = listOf(SourceType.Fpx(), SourceType.TrueMoney),
tokenizationMethods = listOf(TokenizationMethod.GooglePay),
)
private val mockClient: Client = mock()
private val intent =
Intent(
Expand Down Expand Up @@ -93,24 +92,29 @@ class PaymentCreatorActivityTest {

override fun onActivityDestroyed(activity: Activity) {}
}

@Before
fun setUp() {
application.registerActivityLifecycleCallbacks(activityLifecycleCallbacks)
whenever(mockClient.send(any<Request<Capability>>(), any())).doAnswer { invocation ->
val callback = invocation.getArgument<RequestListener<Capability>>(1)
// Capabilities retrieved from api
callback.onRequestSucceed(Capability.create(
allowCreditCard = true,
sourceTypes = listOf(SourceType.TrueMoney,SourceType.PromptPay),
tokenizationMethods = listOf(TokenizationMethod.GooglePay,TokenizationMethod.Card)
))
callback.onRequestSucceed(
Capability.create(
allowCreditCard = true,
sourceTypes = listOf(SourceType.TrueMoney, SourceType.PromptPay),
tokenizationMethods = listOf(TokenizationMethod.GooglePay, TokenizationMethod.Card),
),
)
}
}

@After
fun tearDown() {
reset(mockClient)
application.unregisterActivityLifecycleCallbacks(activityLifecycleCallbacks)
}

@Test
fun initialActivity_collectExtrasIntent() {
ActivityScenario.launchActivityForResult<PaymentCreatorActivity>(intent)
Expand All @@ -129,9 +133,9 @@ class PaymentCreatorActivityTest {

intended(hasComponent(hasClassName(CreditCardActivity::class.java.name)))
}

@Test
fun shouldShowOnlyPaymentMethodsRequestedByMerchantAndAvailableInCapability() {

ActivityScenario.launchActivityForResult<PaymentCreatorActivity>(intent)

onView(
Expand All @@ -149,7 +153,6 @@ class PaymentCreatorActivityTest {
onView(ViewMatchers.withText(R.string.payment_method_fpx_title)).check(doesNotExist())
onView(withId(R.id.recycler_view))
.check(matches(itemCount(3)))

}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ internal inline fun <reified T : Parcelable> Intent.parcelable(key: String?): T?
getParcelableExtra(key)
as? T
}

internal inline fun <reified T : Parcelable?> Intent.parcelableNullable(key: String?): T? =
when {
// https://stackoverflow.com/questions/72571804/getserializableextra-and-getparcelableextra-are-deprecated-what-is-the-alternat/73543350#73543350
SDK_INT >= Build.VERSION_CODES.TIRAMISU -> getParcelableExtra(key, T::class.java)
else ->
@Suppress("DEPRECATION")
getParcelableExtra(key)
as? T
as? T
}
3 changes: 2 additions & 1 deletion sdk/src/main/java/co/omise/android/models/PaymentMethod.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ data class PaymentMethod(
fun createSourceTypeMethod(sourceType: SourceType): PaymentMethod =
PaymentMethod(
name = sourceType.name,
installmentTerms = listOf(), // empty list as it will be replaced by the actual terms from capability
// empty list as it will be replaced by the actual terms from capability
installmentTerms = listOf(),
banks =
when (sourceType) {
is SourceType.Fpx -> sourceType.banks
Expand Down
108 changes: 57 additions & 51 deletions sdk/src/main/java/co/omise/android/ui/PaymentCreatorActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class PaymentCreatorActivity : OmiseActivity() {
private val snackbar: Snackbar by lazy { Snackbar.make(payment_creator_container, "", Snackbar.LENGTH_SHORT) }

private lateinit var client: Client

@TestOnly
fun setClient(client: Client) {
this.client = client
Expand Down Expand Up @@ -100,14 +101,16 @@ class PaymentCreatorActivity : OmiseActivity() {

loadCapability()
}

// Set the menu button to close the view by the user
override fun onCreateOptionsMenu(menu: Menu): Boolean {
if(supportFragmentManager.findFragmentById(R.id.payment_creator_container) !is PaymentChooserFragment){
if (supportFragmentManager.findFragmentById(R.id.payment_creator_container) !is PaymentChooserFragment) {
menuInflater.inflate(R.menu.menu_toolbar, menu)
return true
}
return false
return false
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.close_menu -> {
Expand All @@ -125,24 +128,26 @@ class PaymentCreatorActivity : OmiseActivity() {
errorMessage.visibility = TextView.GONE
// Get capability
val capabilityRequest = Capability.GetCapabilitiesRequestBuilder().build()
client.send(capabilityRequest, object : RequestListener<Capability> {
override fun onRequestSucceed(model: Capability) {

updateActivityWithCapability(model)
// Invalidate the options menu to trigger a refresh and hide the menu button
// as new button will come from the next view
invalidateOptionsMenu()
// Hide loading
progressBar.visibility = ProgressBar.GONE
}
client.send(
capabilityRequest,
object : RequestListener<Capability> {
override fun onRequestSucceed(model: Capability) {
updateActivityWithCapability(model)
// Invalidate the options menu to trigger a refresh and hide the menu button
// as new button will come from the next view
invalidateOptionsMenu()
// Hide loading
progressBar.visibility = ProgressBar.GONE
}

override fun onRequestFailed(throwable: Throwable) {
progressBar.visibility = ProgressBar.GONE
// Show the error message
errorMessage.text = "Unable to load payment methods"
errorMessage.visibility = TextView.VISIBLE
}
})
override fun onRequestFailed(throwable: Throwable) {
progressBar.visibility = ProgressBar.GONE
// Show the error message
errorMessage.text = "Unable to load payment methods"
errorMessage.visibility = TextView.VISIBLE
}
},
)
}

// Detect if the current activity is still active
Expand All @@ -154,29 +159,29 @@ class PaymentCreatorActivity : OmiseActivity() {
capability = newCapability
requester = PaymentCreatorRequesterImpl(client, amount, currency, newCapability)
requester.capability = newCapability
navigation = PaymentCreatorNavigationImpl(
this,
pkey,
amount,
currency,
cardBrands,
googlepayMerchantId,
googlepayRequestBillingAddress,
googlepayRequestPhoneNumber,
REQUEST_CREDIT_CARD,
requester,
newCapability,
)
navigation =
PaymentCreatorNavigationImpl(
this,
pkey,
amount,
currency,
cardBrands,
googlepayMerchantId,
googlepayRequestBillingAddress,
googlepayRequestPhoneNumber,
REQUEST_CREDIT_CARD,
requester,
newCapability,
)
capability = filterCapabilities(newCapability)

// Replace the capability passed from merchant by the new capability
intent.putExtra(EXTRA_CAPABILITY, capability)
// Open the payment method chooser if the activity is still active
if(isActivityActive()){
if (isActivityActive()) {
navigation.navigateToPaymentChooser(capability)
}


requester.listener =
object : PaymentCreatorRequestListener {
override fun onSourceCreated(result: Result<Source>) {
Expand Down Expand Up @@ -210,40 +215,41 @@ class PaymentCreatorActivity : OmiseActivity() {
}
}
}

// Filter the capabilities based on the merchant request and what is available in the capabilities of the merchant account
private fun filterCapabilities(capability:Capability):Capability{
private fun filterCapabilities(capability: Capability): Capability {
val merchantPassedCapabilities = intent.parcelableNullable<Capability?>(EXTRA_CAPABILITY)
var filteredPaymentMethods : List<PaymentMethod>? = null
var filteredTokenizationMethods : List<String>? = null
var filteredPaymentMethods: List<PaymentMethod>? = null
var filteredTokenizationMethods: List<String>? = null

if(merchantPassedCapabilities != null){
if (merchantPassedCapabilities != null) {
val selectedPaymentMethods = merchantPassedCapabilities.paymentMethods
val selectedTokenizationMethods = merchantPassedCapabilities.tokenizationMethods
if(selectedPaymentMethods != null){

filteredPaymentMethods = capability.paymentMethods!!.filter {capMethod->
selectedPaymentMethods.map { it.name }.contains(capMethod.name)
}
if (selectedPaymentMethods != null) {
filteredPaymentMethods =
capability.paymentMethods!!.filter { capMethod ->
selectedPaymentMethods.map { it.name }.contains(capMethod.name)
}
capability.paymentMethods = filteredPaymentMethods.toMutableList()
}
if(selectedTokenizationMethods != null){
filteredTokenizationMethods= capability.tokenizationMethods!!.filter {
selectedTokenizationMethods.contains(it)
}
if (selectedTokenizationMethods != null) {
filteredTokenizationMethods =
capability.tokenizationMethods!!.filter {
selectedTokenizationMethods.contains(it)
}
capability.tokenizationMethods = filteredTokenizationMethods
}
capability.zeroInterestInstallments = merchantPassedCapabilities.zeroInterestInstallments
// add the tokenization methods into payment methods since the SDK only shows paymentMethods
val combinedMethods = capability.paymentMethods?.toMutableList()
capability.tokenizationMethods?.forEach { method->
capability.tokenizationMethods?.forEach { method ->
run {
combinedMethods?.add(PaymentMethod(method))
}
}
capability.paymentMethods = combinedMethods

}
return capability
return capability
}

// TODO: find a way to unit test ActivityResult launcher in order to be able to move from deprecated onActivityResult
Expand Down Expand Up @@ -483,7 +489,7 @@ private class PaymentCreatorNavigationImpl(
}

override fun navigateToDuitNowOBWBankChooser(capability: Capability) {
val banks = capability.paymentMethods?.find { it.name == SourceType.DuitNowOBW.name }?.banks?: emptyList()
val banks = capability.paymentMethods?.find { it.name == SourceType.DuitNowOBW.name }?.banks ?: emptyList()

val fragment =
DuitNowOBWBankChooserFragment.newInstance(banks).apply {
Expand Down

0 comments on commit fff7c99

Please sign in to comment.