Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix parceling of PaymentRelayStarter.Args #2155

Merged
merged 1 commit into from
Feb 10, 2020
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
48 changes: 47 additions & 1 deletion stripe/src/main/java/com/stripe/android/PaymentRelayStarter.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.stripe.android

import android.os.Parcel
import android.os.Parcelable
import com.stripe.android.exception.StripeException
import com.stripe.android.model.PaymentIntent
import com.stripe.android.model.SetupIntent
import com.stripe.android.model.Source
import com.stripe.android.model.StripeIntent
import com.stripe.android.view.AuthActivityStarter
import com.stripe.android.view.PaymentRelayActivity
import kotlinx.android.parcel.Parceler
import kotlinx.android.parcel.Parcelize

/**
Expand Down Expand Up @@ -40,7 +44,7 @@ internal interface PaymentRelayStarter : AuthActivityStarter<PaymentRelayStarter
val source: Source? = null,
val exception: StripeException? = null
) : Parcelable {
internal companion object {
internal companion object : Parceler<Args> {
@JvmSynthetic
internal fun create(stripeIntent: StripeIntent): Args {
return Args(stripeIntent = stripeIntent)
Expand All @@ -55,6 +59,48 @@ internal interface PaymentRelayStarter : AuthActivityStarter<PaymentRelayStarter
internal fun create(exception: StripeException): Args {
return Args(exception = exception)
}

override fun create(parcel: Parcel): Args {
return Args(
stripeIntent = readStripeIntent(parcel),
source = parcel.readParcelable(Source::class.java.classLoader),
exception = parcel.readSerializable() as? StripeException?
)
}

override fun Args.write(parcel: Parcel, flags: Int) {
writeStripeIntent(parcel, stripeIntent)
parcel.writeParcelable(source, 0)
parcel.writeSerializable(exception)
}

private fun readStripeIntent(parcel: Parcel): StripeIntent? {
return when (StripeIntentType.values()[parcel.readInt()]) {
StripeIntentType.PaymentIntent ->
parcel.readParcelable(PaymentIntent::class.java.classLoader)
StripeIntentType.SetupIntent ->
parcel.readParcelable(SetupIntent::class.java.classLoader)
else -> null
}
}

private fun writeStripeIntent(parcel: Parcel, stripeIntent: StripeIntent?) {
val stripeIntentType = when (stripeIntent) {
is PaymentIntent -> StripeIntentType.PaymentIntent
is SetupIntent -> StripeIntentType.SetupIntent
else -> StripeIntentType.None
}
parcel.writeInt(stripeIntentType.ordinal)
stripeIntent?.let {
parcel.writeParcelable(it, 0)
}
}

private enum class StripeIntentType {
None,
PaymentIntent,
SetupIntent
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ import com.nhaarman.mockitokotlin2.eq
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import com.stripe.android.exception.APIException
import com.stripe.android.exception.InvalidRequestException
import com.stripe.android.exception.PermissionException
import com.stripe.android.model.PaymentIntentFixtures
import com.stripe.android.model.SetupIntentFixtures
import com.stripe.android.model.SourceFixtures
import com.stripe.android.utils.ParcelUtils.verifyParcelRoundtrip
import com.stripe.android.view.AuthActivityStarter
import kotlin.test.Test
import kotlin.test.assertEquals
Expand Down Expand Up @@ -75,6 +79,61 @@ class PaymentRelayStarterTest {
assertEquals(exception, result.exception)
}

@Test
fun testParcel_withPaymentIntent() {
verifyParcelRoundtrip(
PaymentRelayStarter.Args(
stripeIntent = PaymentIntentFixtures.PI_REQUIRES_MASTERCARD_3DS2,
source = SourceFixtures.CARD,
exception = InvalidRequestException(
stripeError = StripeErrorFixtures.INVALID_REQUEST_ERROR,
cause = IllegalArgumentException()
)
)
)
}

@Test
fun testParcel_withSetupIntent() {
verifyParcelRoundtrip(
PaymentRelayStarter.Args(
stripeIntent = SetupIntentFixtures.SI_NEXT_ACTION_REDIRECT,
source = SourceFixtures.CARD,
exception = InvalidRequestException(
stripeError = StripeErrorFixtures.INVALID_REQUEST_ERROR,
cause = IllegalArgumentException()
)
)
)
}

@Test
fun testParcel_withoutStripeIntent() {
verifyParcelRoundtrip(
PaymentRelayStarter.Args(
stripeIntent = null,
source = SourceFixtures.CARD,
exception = InvalidRequestException(
stripeError = StripeErrorFixtures.INVALID_REQUEST_ERROR,
cause = IllegalArgumentException()
)
)
)
}

@Test
fun testParcel_withStripeIntentwithoutSource() {
verifyParcelRoundtrip(
PaymentRelayStarter.Args(
stripeIntent = SetupIntentFixtures.SI_NEXT_ACTION_REDIRECT,
exception = InvalidRequestException(
stripeError = StripeErrorFixtures.INVALID_REQUEST_ERROR,
cause = IllegalArgumentException()
)
)
)
}

private val result: PaymentController.Result
get() {
return requireNotNull(
Expand Down
12 changes: 12 additions & 0 deletions stripe/src/test/java/com/stripe/android/utils/ParcelUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.stripe.android.utils
import android.os.Bundle
import android.os.Parcel
import android.os.Parcelable
import kotlin.test.assertEquals

internal object ParcelUtils {
/**
Expand Down Expand Up @@ -35,5 +36,16 @@ internal object ParcelUtils {
return creator.createFromParcel(parcel)
}

internal fun verifyParcelRoundtrip(expected: Parcelable) {
val bundle = Bundle().also {
it.putParcelable(KEY, expected)
}

val actual = copy(bundle, Bundle.CREATOR)
.getParcelable<Parcelable>(KEY)

assertEquals(expected, actual)
}

private const val KEY = "parcelable"
}