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 address lookup view state #1991

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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 @@ -507,6 +507,7 @@ class DefaultCardDelegate(

override fun handleBackPress(): Boolean {
return if (_viewFlow.value == CardComponentViewType.AddressLookup) {
addressDelegate.updateAddressInputData { reset() }
_viewFlow.tryEmit(CardComponentViewType.DefaultCardView)
true
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import com.adyen.checkout.test.TestDispatcherExtension
import com.adyen.checkout.test.extensions.test
import com.adyen.checkout.ui.core.internal.data.api.AddressRepository
import com.adyen.checkout.ui.core.internal.data.api.TestAddressRepository
import com.adyen.checkout.ui.core.internal.ui.AddressDelegate
import com.adyen.checkout.ui.core.internal.ui.AddressFormUIState
import com.adyen.checkout.ui.core.internal.ui.AddressLookupDelegate
import com.adyen.checkout.ui.core.internal.ui.SubmitHandler
Expand Down Expand Up @@ -1231,6 +1232,7 @@ internal class DefaultCardDelegateTest(
@Test
fun `when view type is AddressLookup and handleBackPress() is called DefaultCardView should be emitted`() =
runTest {
whenever(addressLookupDelegate.addressDelegate) doReturn mock()
delegate.initialize(CoroutineScope(UnconfinedTestDispatcher()))
delegate.startAddressLookup()
assertTrue(delegate.handleBackPress())
Expand All @@ -1240,6 +1242,19 @@ internal class DefaultCardDelegateTest(
}
}

@Test
fun `when view type is AddressLookup and handleBackPress() is called, then address form data should be reset`() =
runTest {
val addressDelegate = mock<AddressDelegate>()
whenever(addressLookupDelegate.addressDelegate) doReturn addressDelegate
delegate.initialize(CoroutineScope(UnconfinedTestDispatcher()))
delegate.startAddressLookup()

delegate.handleBackPress()

verify(addressDelegate).updateAddressInputData(any())
}

@Test
fun `when view type is DefaultCardView and handleBackPress() is called it should return false`() = runTest {
delegate.initialize(CoroutineScope(UnconfinedTestDispatcher()))
Expand Down
11 changes: 11 additions & 0 deletions example-app/src/main/assets/lookup_options.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@
"city": "Amsterdam"
}
},
{
"id": "5",
"address": {
"country": "NL",
"postalCode": "1012KK",
"houseNumberOrName": "49",
"street": "Rokin",
"stateOrProvince": "Noord-Holland",
"city": "Amsterdam"
}
},
{
"id": "1",
"address": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.adyen.checkout.ui.core.internal.ui.AddressDelegate
import com.adyen.checkout.ui.core.internal.ui.AddressSpecification
import com.adyen.checkout.ui.core.internal.ui.SimpleTextListAdapter
import com.adyen.checkout.ui.core.internal.ui.model.AddressListItem
import com.adyen.checkout.ui.core.internal.ui.model.AddressOutputData
import com.adyen.checkout.ui.core.internal.util.hideError
import com.adyen.checkout.ui.core.internal.util.setLocalizedHintFromStyle
import com.adyen.checkout.ui.core.internal.util.setLocalizedTextFromStyle
Expand Down Expand Up @@ -121,7 +122,8 @@ class AddressFormInput @JvmOverloads constructor(
val selectedCountryCode = countryAdapter.getItem(position).code
if (delegate.addressOutputData.country.value != selectedCountryCode) {
delegate.updateAddressInputData {
reset()
// Only reset state/province, so filled in data is retained.
stateOrProvince = ""
country = selectedCountryCode
}
populateFormFields(AddressSpecification.fromString(selectedCountryCode))
Expand Down Expand Up @@ -220,6 +222,8 @@ class AddressFormInput @JvmOverloads constructor(
currentSpec = selectedSpecification
autoCompleteTextViewCountry?.setText(selectedCountry?.name)
populateFormFields(selectedSpecification)
} else {
updateInputFields(delegate.addressOutputData)
}
}

Expand Down Expand Up @@ -248,6 +252,7 @@ class AddressFormInput @JvmOverloads constructor(
val hadFocus = hasFocus()
formContainer?.removeAllViews()
LayoutInflater.from(context).inflate(layoutResId, formContainer, true)
updateInputFields(delegate.addressOutputData)
initForm(specification)
if (hadFocus) requestFocus()
}
Expand Down Expand Up @@ -314,7 +319,7 @@ class AddressFormInput @JvmOverloads constructor(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setAutofillHints(HintConstants.AUTOFILL_HINT_POSTAL_ADDRESS_STREET_ADDRESS)
}
setText(delegate.addressOutputData.street.value)

setOnChangeListener {
delegate.updateAddressInputData { street = it.toString() }
textInputLayoutStreet?.hideError()
Expand All @@ -333,7 +338,6 @@ class AddressFormInput @JvmOverloads constructor(
private fun initHouseNumberInput(styleResId: Int?) {
styleResId?.let { textInputLayoutHouseNumber?.setLocalizedHintFromStyle(it, localizedContext) }
editTextHouseNumber?.apply {
setText(delegate.addressOutputData.houseNumberOrName.value)
setOnChangeListener {
delegate.updateAddressInputData { houseNumberOrName = it.toString() }
textInputLayoutHouseNumber?.hideError()
Expand All @@ -355,7 +359,7 @@ class AddressFormInput @JvmOverloads constructor(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setAutofillHints(HintConstants.AUTOFILL_HINT_POSTAL_ADDRESS_APT_NUMBER)
}
setText(delegate.addressOutputData.apartmentSuite.value)

setOnChangeListener {
delegate.updateAddressInputData { apartmentSuite = it.toString() }
}
Expand All @@ -376,7 +380,7 @@ class AddressFormInput @JvmOverloads constructor(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setAutofillHints(HintConstants.AUTOFILL_HINT_POSTAL_CODE)
}
setText(delegate.addressOutputData.postalCode.value)

setOnChangeListener {
delegate.updateAddressInputData { postalCode = it.toString() }
textInputLayoutPostalCode?.hideError()
Expand All @@ -398,7 +402,7 @@ class AddressFormInput @JvmOverloads constructor(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setAutofillHints(HintConstants.AUTOFILL_HINT_POSTAL_ADDRESS_LOCALITY)
}
setText(delegate.addressOutputData.city.value)

setOnChangeListener {
delegate.updateAddressInputData { city = it.toString() }
textInputLayoutCity?.hideError()
Expand All @@ -420,7 +424,7 @@ class AddressFormInput @JvmOverloads constructor(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setAutofillHints(HintConstants.AUTOFILL_HINT_POSTAL_ADDRESS_REGION)
}
setText(delegate.addressOutputData.stateOrProvince.value)

setOnChangeListener {
delegate.updateAddressInputData { stateOrProvince = it.toString() }
textInputLayoutProvinceTerritory?.hideError()
Expand Down Expand Up @@ -452,6 +456,21 @@ class AddressFormInput @JvmOverloads constructor(
}
}

private fun updateInputFields(outputData: AddressOutputData) {
editTextStreet?.setTextIfChanged(outputData.street.value)
editTextHouseNumber?.setTextIfChanged(outputData.houseNumberOrName.value)
editTextApartmentSuite?.setTextIfChanged(outputData.apartmentSuite.value)
editTextPostalCode?.setTextIfChanged(outputData.postalCode.value)
editTextCity?.setTextIfChanged(outputData.city.value)
editTextProvinceTerritory?.setTextIfChanged(outputData.stateOrProvince.value)
}

private fun TextView.setTextIfChanged(newText: String?) {
if (newText != text.toString()) {
text = newText
}
}

fun updateAddressHint(isOptional: Boolean) {
val spec = AddressSpecification.fromString(delegate.addressOutputData.country.value)

Expand Down