Skip to content

Commit

Permalink
Refactor CustomerSession.setCustomerShippingInformation()
Browse files Browse the repository at this point in the history
Previously, the result of this method was delivered via
`LocalBroadcastManager`. Use a callback object to deliver
the result like all the other API binding methods on
`CustomerSession`. Also update `PaymentFlowActivity`
accordingly.
  • Loading branch information
mshafrir-stripe committed Oct 29, 2019
1 parent 9005bdd commit 89116fd
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 81 deletions.
30 changes: 13 additions & 17 deletions stripe/src/main/java/com/stripe/android/CustomerSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;

import androidx.annotation.NonNull;
Expand Down Expand Up @@ -38,8 +37,6 @@ public class CustomerSession {
public static final String ACTION_API_EXCEPTION = "action_api_exception";
public static final String EXTRA_EXCEPTION = "exception";

public static final String EVENT_SHIPPING_INFO_SAVED = "shipping_info_saved";

static final String ACTION_ADD_SOURCE = "add_source";
static final String ACTION_DELETE_SOURCE = "delete_source";
static final String ACTION_ATTACH_PAYMENT_METHOD = "attach_payment_method";
Expand Down Expand Up @@ -67,7 +64,6 @@ public class CustomerSession {

@Nullable private Customer mCustomer;
private long mCustomerCacheTime;
@NonNull private final LocalBroadcastManager mLocalBroadcastManager;
@NonNull private final OperationIdFactory mOperationIdFactory;
@NonNull private final EphemeralKeyManager mEphemeralKeyManager;
@Nullable private final Calendar mProxyNowCalendar;
Expand Down Expand Up @@ -200,7 +196,6 @@ private CustomerSession(@NonNull Context context, @NonNull EphemeralKeyProvider
@Nullable String stripeAccountId,
boolean shouldPrefetchEphemeralKey) {
mOperationIdFactory = new OperationIdFactory();
mLocalBroadcastManager = LocalBroadcastManager.getInstance(context);
mThreadPoolExecutor = threadPoolExecutor;
mProxyNowCalendar = proxyNowCalendar;
mProductUsage = new CustomerSessionProductUsage();
Expand All @@ -209,7 +204,7 @@ private CustomerSession(@NonNull Context context, @NonNull EphemeralKeyProvider
new CustomerSessionRunnableFactory(
stripeRepository,
createHandler(),
mLocalBroadcastManager,
LocalBroadcastManager.getInstance(context),
publishableKey,
stripeAccountId,
mProductUsage
Expand All @@ -234,8 +229,7 @@ public void onCustomerRetrieved(@Nullable Customer customer,
mCustomer = customer;
mCustomerCacheTime = getCalendarInstance().getTimeInMillis();

final CustomerRetrievalListener listener =
getListener(operationId);
final CustomerRetrievalListener listener = getListener(operationId);
if (listener != null && customer != null) {
listener.onCustomerRetrieved(customer);
}
Expand All @@ -253,8 +247,7 @@ public void onSourceRetrieved(@Nullable Source source,
@Override
public void onPaymentMethodRetrieved(@Nullable PaymentMethod paymentMethod,
@NonNull String operationId) {
final PaymentMethodRetrievalListener listener =
getListener(operationId);
final PaymentMethodRetrievalListener listener = getListener(operationId);
if (listener != null && paymentMethod != null) {
listener.onPaymentMethodRetrieved(paymentMethod);
}
Expand All @@ -263,18 +256,20 @@ public void onPaymentMethodRetrieved(@Nullable PaymentMethod paymentMethod,
@Override
public void onPaymentMethodsRetrieved(@NonNull List<PaymentMethod> paymentMethods,
@NonNull String operationId) {
final PaymentMethodsRetrievalListener listener =
getListener(operationId);
final PaymentMethodsRetrievalListener listener = getListener(operationId);
if (listener != null) {
listener.onPaymentMethodsRetrieved(paymentMethods);
}
}

@Override
public void onCustomerShippingInfoSaved(@Nullable Customer customer) {
public void onCustomerShippingInfoSaved(@Nullable Customer customer,
@NonNull String operationId) {
mCustomer = customer;
mLocalBroadcastManager
.sendBroadcast(new Intent(EVENT_SHIPPING_INFO_SAVED));
final CustomerRetrievalListener listener = getListener(operationId);
if (listener != null && customer != null) {
listener.onCustomerRetrieved(customer);
}
}

@Override
Expand Down Expand Up @@ -418,10 +413,11 @@ public void getPaymentMethods(@NonNull PaymentMethod.Type paymentMethodType,
* @param shippingInformation the data to be set
*/
public void setCustomerShippingInformation(
@NonNull ShippingInformation shippingInformation) {
@NonNull ShippingInformation shippingInformation,
@NonNull CustomerRetrievalListener listener) {
final Map<String, Object> arguments = new HashMap<>();
arguments.put(KEY_SHIPPING_INFO, shippingInformation);
startOperation(ACTION_SET_CUSTOMER_SHIPPING_INFO, arguments, null);
startOperation(ACTION_SET_CUSTOMER_SHIPPING_INFO, arguments, listener);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal class CustomerSessionHandler(
listener.onPaymentMethodRetrieved(obj as PaymentMethod, operationId)
}
CustomerSessionRunnableFactory.MessageCode.CUSTOMER_SHIPPING_INFO_SAVED -> {
listener.onCustomerShippingInfoSaved(obj as Customer)
listener.onCustomerShippingInfoSaved(obj as Customer, operationId)
}
CustomerSessionRunnableFactory.MessageCode.PAYMENT_METHODS_RETRIEVED -> {
listener.onPaymentMethodsRetrieved(obj as List<PaymentMethod>, operationId)
Expand All @@ -55,7 +55,7 @@ internal class CustomerSessionHandler(

fun onPaymentMethodsRetrieved(paymentMethods: List<PaymentMethod>, operationId: String)

fun onCustomerShippingInfoSaved(customer: Customer?)
fun onCustomerShippingInfoSaved(customer: Customer?, operationId: String)

fun onError(exception: StripeException, operationId: String)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import org.json.JSONObject
*/
@Parcelize
data class ShippingInformation constructor(
val address: Address?,
val name: String?,
val phone: String?
val address: Address? = null,
val name: String? = null,
val phone: String? = null
) : StripeModel(), StripeParamsModel, Parcelable {

override fun toParamMap(): Map<String, Any> {
Expand All @@ -34,11 +34,13 @@ data class ShippingInformation constructor(
fun fromJson(jsonObject: JSONObject?): ShippingInformation? {
return if (jsonObject == null) {
null
} else ShippingInformation(
Address.fromJson(jsonObject.optJSONObject(FIELD_ADDRESS)),
optString(jsonObject, FIELD_NAME),
optString(jsonObject, FIELD_PHONE)
)
} else {
ShippingInformation(
Address.fromJson(jsonObject.optJSONObject(FIELD_ADDRESS)),
optString(jsonObject, FIELD_NAME),
optString(jsonObject, FIELD_PHONE)
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import com.stripe.android.view.CardInputListener.FocusField.Companion.FOCUS_EXPI
import com.stripe.android.view.CardInputListener.FocusField.Companion.FOCUS_POSTAL
import java.math.BigDecimal
import java.math.RoundingMode
import java.util.Objects

/**
* A multiline card input widget using the support design library's [TextInputLayout]
Expand Down Expand Up @@ -143,7 +142,7 @@ class CardMultilineWidget @JvmOverloads constructor(
}

val cardNumber = cardNumberEditText.cardNumber
val cardDate = Objects.requireNonNull<IntArray>(expiryDateEditText.validDateFields)
val cardDate = requireNotNull(expiryDateEditText.validDateFields)
val cvcValue = cvcEditText.text?.toString()

return Card.Builder(cardNumber, cardDate[0], cardDate[1], cvcValue)
Expand Down
51 changes: 30 additions & 21 deletions stripe/src/main/java/com/stripe/android/view/PaymentFlowActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import android.view.inputmethod.InputMethodManager
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.viewpager.widget.ViewPager
import com.stripe.android.CustomerSession
import com.stripe.android.CustomerSession.EVENT_SHIPPING_INFO_SAVED
import com.stripe.android.PaymentSession.Companion.STATE_PAYMENT_SESSION_DATA
import com.stripe.android.PaymentSession.Companion.TOKEN_PAYMENT_SESSION
import com.stripe.android.PaymentSessionData
import com.stripe.android.R
import com.stripe.android.StripeError
import com.stripe.android.model.Customer
import com.stripe.android.model.ShippingInformation
import com.stripe.android.model.ShippingMethod
import kotlinx.android.synthetic.main.activity_shipping_flow.*
Expand All @@ -25,7 +26,6 @@ import kotlinx.android.synthetic.main.activity_shipping_flow.*
*/
class PaymentFlowActivity : StripeActivity() {

private lateinit var shippingInfoSavedBroadcastReceiver: BroadcastReceiver
private lateinit var shippingInfoSubmittedBroadcastReceiver: BroadcastReceiver
private lateinit var paymentFlowPagerAdapter: PaymentFlowPagerAdapter
private lateinit var paymentSessionData: PaymentSessionData
Expand Down Expand Up @@ -92,12 +92,7 @@ class PaymentFlowActivity : StripeActivity() {
}
}
}
shippingInfoSavedBroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
onShippingMethodsReady(validShippingMethods, defaultShippingMethod)
paymentSessionData.shippingInformation = shippingInformationSubmitted
}
}

title = paymentFlowPagerAdapter.getPageTitle(shipping_flow_viewpager.currentItem)
}

Expand All @@ -111,27 +106,42 @@ class PaymentFlowActivity : StripeActivity() {

override fun onPause() {
super.onPause()
val localBroadcastManager = LocalBroadcastManager.getInstance(this)
localBroadcastManager.unregisterReceiver(shippingInfoSubmittedBroadcastReceiver)
localBroadcastManager.unregisterReceiver(shippingInfoSavedBroadcastReceiver)
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(shippingInfoSubmittedBroadcastReceiver)
}

override fun onResume() {
super.onResume()
val localBroadcastManager = LocalBroadcastManager.getInstance(this)
localBroadcastManager.registerReceiver(
LocalBroadcastManager.getInstance(this).registerReceiver(
shippingInfoSubmittedBroadcastReceiver,
IntentFilter(PaymentFlowExtras.EVENT_SHIPPING_INFO_PROCESSED)
)
localBroadcastManager.registerReceiver(
shippingInfoSavedBroadcastReceiver,
IntentFilter(EVENT_SHIPPING_INFO_SAVED)
)
}

@JvmSynthetic
internal fun onShippingInfoSaved(shippingInformation: ShippingInformation) {
onShippingMethodsReady(validShippingMethods, defaultShippingMethod)
paymentSessionData.shippingInformation = shippingInformation
}

private fun onShippingInfoValidated(customerSession: CustomerSession) {
shippingInformationSubmitted?.let {
customerSession.setCustomerShippingInformation(it)
customerSession.setCustomerShippingInformation(it,
object : CustomerSession.CustomerRetrievalListener {
override fun onCustomerRetrieved(customer: Customer) {
onShippingInfoSaved(
customer.shippingInformation ?: ShippingInformation()
)
}

override fun onError(
errorCode: Int,
errorMessage: String,
stripeError: StripeError?
) {
showError(errorMessage)
}
})
}
}

Expand All @@ -155,9 +165,8 @@ class PaymentFlowActivity : StripeActivity() {
private fun onShippingInfoSubmitted() {
hideKeyboard()

val shippingInfoWidget = findViewById<ShippingInfoWidget>(R.id.shipping_info_widget)
val shippingInformation = shippingInfoWidget.shippingInformation
if (shippingInformation != null) {
val shippingInfoWidget: ShippingInfoWidget = findViewById(R.id.shipping_info_widget)
shippingInfoWidget.shippingInformation?.let { shippingInformation ->
shippingInformationSubmitted = shippingInformation
setCommunicatingProgress(true)
broadcastShippingInfoSubmitted(shippingInformation)
Expand Down
23 changes: 15 additions & 8 deletions stripe/src/test/java/com/stripe/android/CustomerSessionTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import com.stripe.android.model.Customer
import com.stripe.android.model.CustomerFixtures
import com.stripe.android.model.PaymentMethod
import com.stripe.android.model.PaymentMethodFixtures
import com.stripe.android.model.ShippingInformation
import com.stripe.android.model.Source
import com.stripe.android.model.SourceFixtures
import com.stripe.android.testharness.JsonTestUtils
Expand All @@ -31,7 +30,6 @@ import com.stripe.android.view.PaymentFlowActivity
import com.stripe.android.view.PaymentFlowActivityStarter
import com.stripe.android.view.PaymentMethodsActivity
import java.util.Calendar
import java.util.Objects
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit
import kotlin.test.AfterTest
Expand Down Expand Up @@ -220,16 +218,25 @@ class CustomerSessionTest : BaseViewTest<PaymentFlowActivity>(PaymentFlowActivit
@Throws(CardException::class, APIException::class, InvalidRequestException::class,
AuthenticationException::class, APIConnectionException::class, JSONException::class)
fun setCustomerShippingInfo_withValidInfo_callsWithExpectedArgs() {
val firstKey = Objects.requireNonNull(
getCustomerEphemeralKey(FIRST_SAMPLE_KEY_RAW))
val firstKey = getCustomerEphemeralKey(FIRST_SAMPLE_KEY_RAW)
ephemeralKeyProvider.setNextRawEphemeralKey(FIRST_SAMPLE_KEY_RAW)
val proxyCalendar = Calendar.getInstance()
val customerSession = createCustomerSession(proxyCalendar)
customerSession.addProductUsageTokenIfValid(PaymentMethodsActivity.TOKEN_PAYMENT_METHODS_ACTIVITY)
val shippingInformation = Objects.requireNonNull<ShippingInformation>(
CustomerFixtures.CUSTOMER_WITH_SHIPPING.shippingInformation
)
customerSession.setCustomerShippingInformation(shippingInformation)
val shippingInformation =
requireNotNull(CustomerFixtures.CUSTOMER_WITH_SHIPPING.shippingInformation)
customerSession.setCustomerShippingInformation(shippingInformation,
object : CustomerSession.CustomerRetrievalListener {
override fun onCustomerRetrieved(customer: Customer) {
}

override fun onError(
errorCode: Int,
errorMessage: String,
stripeError: StripeError?
) {
}
})

assertNotNull(FIRST_CUSTOMER.id)
verify<StripeRepository>(stripeRepository).setCustomerShippingInfo(
Expand Down
6 changes: 3 additions & 3 deletions stripe/src/test/java/com/stripe/android/PaymentSessionTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import com.stripe.android.view.PaymentFlowActivity
import com.stripe.android.view.PaymentFlowActivityStarter
import com.stripe.android.view.PaymentMethodsActivity
import com.stripe.android.view.PaymentMethodsActivityStarter
import java.util.Objects
import java.util.concurrent.ThreadPoolExecutor
import kotlin.test.BeforeTest
import kotlin.test.Test
Expand Down Expand Up @@ -210,8 +209,9 @@ class PaymentSessionTest {

@Test
fun getSelectedPaymentMethodId_whenHasPrefsSet_returnsExpectedId() {
val customerId = Objects.requireNonNull<String>(FIRST_CUSTOMER.id)
`when`<String>(paymentSessionPrefs.getSelectedPaymentMethodId(customerId)).thenReturn("pm_12345")
val customerId = requireNotNull(FIRST_CUSTOMER.id)
`when`<String>(paymentSessionPrefs.getSelectedPaymentMethodId(customerId))
.thenReturn("pm_12345")

`when`<Customer>(customerSession.cachedCustomer).thenReturn(FIRST_CUSTOMER)
CustomerSession.setInstance(customerSession)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import androidx.test.core.app.ApplicationProvider
import java.util.Objects
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
Expand Down Expand Up @@ -73,7 +72,7 @@ class TelemetryClientUtilTest {
)
.createTelemetryMap()

val secondMap = Objects.requireNonNull<Map<*, *>>(telemetryMap["b"] as Map<*, *>?)
val secondMap = telemetryMap["b"] as Map<*, *>
assertEquals(9, secondMap.size)
assertEquals("version_name", secondMap["l"])
}
Expand Down
3 changes: 1 addition & 2 deletions stripe/src/test/java/com/stripe/android/model/CardTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.stripe.android.model
import com.stripe.android.model.Card.Companion.asCardBrand
import com.stripe.android.model.Card.Companion.asFundingType
import java.util.Calendar
import java.util.Objects
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
Expand Down Expand Up @@ -634,7 +633,7 @@ class CardTest {

@Test
fun toBuilder_withLoggingToken_whenUnchanged_isEquals() {
val card = Objects.requireNonNull<Card>(Card.fromJson(JSON_CARD_USD))
val card = requireNotNull(Card.fromJson(JSON_CARD_USD))
card.toBuilder()
.loggingTokens(listOf("hello"))

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.stripe.android.model

import java.util.Objects
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
Expand Down Expand Up @@ -73,8 +72,8 @@ class ConfirmSetupIntentParamsTest {
)
val params = confirmSetupIntentParams.toParamMap()
assertNull(params[ConfirmStripeIntentParams.API_PARAM_PAYMENT_METHOD_ID])
val paymentMethodData = Objects.requireNonNull<Any>(
params[ConfirmStripeIntentParams.API_PARAM_PAYMENT_METHOD_DATA]) as Map<String, Any>
val paymentMethodData =
params[ConfirmStripeIntentParams.API_PARAM_PAYMENT_METHOD_DATA] as Map<String, Any>
assertEquals("card", paymentMethodData["type"])
assertNotNull(paymentMethodData["card"])
}
Expand Down
Loading

0 comments on commit 89116fd

Please sign in to comment.