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

Re-render shipping methods screen when shipping methods change #2887

Merged
merged 1 commit into from
Sep 23, 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
Original file line number Diff line number Diff line change
Expand Up @@ -246,16 +246,24 @@ class PaymentSessionActivity : AppCompatActivity() {

private class ShippingInformationValidator : PaymentSessionConfig.ShippingInformationValidator {
override fun isValid(shippingInformation: ShippingInformation): Boolean {
return shippingInformation.address?.country == Locale.US.country
return setOf(Locale.US.country, Locale.CANADA.country)
.contains(shippingInformation.address?.country.orEmpty())
}

override fun getErrorMessage(shippingInformation: ShippingInformation): String {
return "The country must be US."
return "The country must be US or Canada."
}
}

private class ShippingMethodsFactory : PaymentSessionConfig.ShippingMethodsFactory {
override fun create(shippingInformation: ShippingInformation) = SHIPPING_METHODS
override fun create(
shippingInformation: ShippingInformation
): List<ShippingMethod> {
return when (shippingInformation.address?.country) {
"CA" -> SHIPPING_METHODS_CA
else -> SHIPPING_METHODS_US
}
}
}

private fun hideProgressBar() {
Expand Down Expand Up @@ -327,7 +335,17 @@ class PaymentSessionActivity : AppCompatActivity() {
"(555) 555-5555"
)

private val SHIPPING_METHODS = listOf(
private val SHIPPING_METHODS_CA = listOf(
ShippingMethod(
"Canada Post",
"canada-post",
599,
"CAD",
"Arrives in 3-5 days"
)
)

private val SHIPPING_METHODS_US = listOf(
ShippingMethod(
"UPS Ground",
"ups-ground",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.stripe.android.databinding.ShippingInfoPageBinding
import com.stripe.android.databinding.ShippingMethodPageBinding
import com.stripe.android.model.ShippingInformation
import com.stripe.android.model.ShippingMethod
import kotlin.properties.Delegates

internal class PaymentFlowPagerAdapter(
private val context: Context,
Expand Down Expand Up @@ -43,20 +44,23 @@ internal class PaymentFlowPagerAdapter(
notifyDataSetChanged()
}

internal var shippingMethods: List<ShippingMethod> = emptyList()
set(value) {
field = value
notifyDataSetChanged()
}
private var shouldRecreateShippingMethodsScreen = false

internal var selectedShippingMethod: ShippingMethod? = null
set(value) {
field = value
notifyDataSetChanged()
}
internal var shippingMethods: List<ShippingMethod> by Delegates.observable(
emptyList()
) { _, oldValue, newValue ->
shouldRecreateShippingMethodsScreen = newValue != oldValue
}

internal var selectedShippingMethod: ShippingMethod? by Delegates.observable(
null
) { _, oldValue, newValue ->
shouldRecreateShippingMethodsScreen = newValue != oldValue
}

override fun instantiateItem(collection: ViewGroup, position: Int): Any {
val viewHolder = when (pages[position]) {
val page = pages[position]
val viewHolder = when (page) {
PaymentFlowPage.ShippingInfo -> {
PaymentFlowViewHolder.ShippingInformationViewHolder(collection)
}
Expand All @@ -81,6 +85,7 @@ internal class PaymentFlowPagerAdapter(
}
}
collection.addView(viewHolder.itemView)
viewHolder.itemView.tag = page
return viewHolder.itemView
}

Expand All @@ -104,7 +109,22 @@ internal class PaymentFlowPagerAdapter(
return context.getString(pages[position].titleResId)
}

internal sealed class PaymentFlowViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
override fun getItemPosition(obj: Any): Int {
return if (obj is View && obj.tag == PaymentFlowPage.ShippingMethod &&
shouldRecreateShippingMethodsScreen
) {
// if the shipping methods screen needs to be updated, return `POSITION_NONE` to
// indicate that the item is no longer valid and should be recreated
shouldRecreateShippingMethodsScreen = false
POSITION_NONE
} else {
super.getItemPosition(obj)
}
}

internal sealed class PaymentFlowViewHolder(
itemView: View
) : RecyclerView.ViewHolder(itemView) {
class ShippingInformationViewHolder(
viewBinding: ShippingInfoPageBinding
) : PaymentFlowViewHolder(viewBinding.root) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.stripe.android.view

import androidx.test.core.app.ApplicationProvider
import com.nhaarman.mockitokotlin2.mock
import com.stripe.android.CustomerSession
import com.stripe.android.PaymentSessionFixtures
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
Expand All @@ -12,14 +10,10 @@ import kotlin.test.assertEquals
@RunWith(RobolectricTestRunner::class)
class PaymentFlowPagerAdapterTest {

private val customerSession: CustomerSession = mock()

private val adapter: PaymentFlowPagerAdapter by lazy {
PaymentFlowPagerAdapter(
ApplicationProvider.getApplicationContext(),
PaymentSessionFixtures.CONFIG
)
}
private val adapter = PaymentFlowPagerAdapter(
ApplicationProvider.getApplicationContext(),
PaymentSessionFixtures.CONFIG
)

@Test
fun pageCount_updatesAfterSavingShippingInfo() {
Expand Down