diff --git a/paymentsheet/api/paymentsheet.api b/paymentsheet/api/paymentsheet.api index edd0a6cc47d..a3325502df3 100644 --- a/paymentsheet/api/paymentsheet.api +++ b/paymentsheet/api/paymentsheet.api @@ -791,19 +791,19 @@ public final class com/stripe/android/paymentsheet/addresselement/AddressLaunche public synthetic fun newArray (I)[Ljava/lang/Object; } -public final class com/stripe/android/paymentsheet/addresselement/AddressLauncherResult$Canceled$Creator : android/os/Parcelable$Creator { +public final class com/stripe/android/paymentsheet/addresselement/AddressLauncher$DefaultAddressDetails$Creator : android/os/Parcelable$Creator { public fun ()V - public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/paymentsheet/addresselement/AddressLauncherResult$Canceled; + public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/paymentsheet/addresselement/AddressLauncher$DefaultAddressDetails; public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object; - public final fun newArray (I)[Lcom/stripe/android/paymentsheet/addresselement/AddressLauncherResult$Canceled; + public final fun newArray (I)[Lcom/stripe/android/paymentsheet/addresselement/AddressLauncher$DefaultAddressDetails; public synthetic fun newArray (I)[Ljava/lang/Object; } -public final class com/stripe/android/paymentsheet/addresselement/AddressLauncherResult$Failed$Creator : android/os/Parcelable$Creator { +public final class com/stripe/android/paymentsheet/addresselement/AddressLauncherResult$Canceled$Creator : android/os/Parcelable$Creator { public fun ()V - public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/paymentsheet/addresselement/AddressLauncherResult$Failed; + public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/paymentsheet/addresselement/AddressLauncherResult$Canceled; public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object; - public final fun newArray (I)[Lcom/stripe/android/paymentsheet/addresselement/AddressLauncherResult$Failed; + public final fun newArray (I)[Lcom/stripe/android/paymentsheet/addresselement/AddressLauncherResult$Canceled; public synthetic fun newArray (I)[Ljava/lang/Object; } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressDetails.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressDetails.kt index d7b7f5a46fb..2c0491ed83b 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressDetails.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressDetails.kt @@ -1,22 +1,41 @@ package com.stripe.android.paymentsheet.addresselement import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import com.stripe.android.paymentsheet.PaymentSheet +import kotlinx.parcelize.Parcelize @Parcelize internal data class AddressDetails( + /** + * The customer's full name + */ val name: String? = null, - val company: String? = null, - val city: String? = null, - val country: String? = null, - val line1: String? = null, - val line2: String? = null, - val postalCode: String? = null, - val state: String? = null, + + /** + * The customer's address + */ + val address: PaymentSheet.Address? = null, + + /** + * The customer's phone number, without formatting e.g. "5551234567" + */ val phoneNumber: String? = null, - val checkboxChecked: Boolean? = null + + /** + * Whether or not your custom checkbox is selected. + * Note: The checkbox is displayed below the other fields when AdditionalFieldsConfiguration.checkboxLabel is set. + */ + val isCheckboxSelected: Boolean? = null ) : Parcelable { companion object { - const val KEY = "ShippingAddress" + const val KEY = "AddressDetails" } } + +internal fun AddressLauncher.DefaultAddressDetails.toAddressDetails(): AddressDetails = + AddressDetails( + name = this.name, + address = this.address, + phoneNumber = this.phoneNumber, + isCheckboxSelected = this.isCheckboxSelected + ) diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressLauncher.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressLauncher.kt index 5b69c240ccf..ec82cf0986c 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressLauncher.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressLauncher.kt @@ -78,7 +78,7 @@ internal class AddressLauncher internal constructor( /** * The values to pre-populate shipping address fields with. */ - val defaultValues: AddressDetails? = null, + val defaultValues: DefaultAddressDetails? = null, /** * A list of two-letter country codes representing countries the customers can select. @@ -108,10 +108,10 @@ internal class AddressLauncher internal constructor( * Google Places api key used to provide autocomplete suggestions * When null, autocomplete is disabled. */ - val googlePlacesApiKey: String? = "", + val googlePlacesApiKey: String? = null, /** - * The label of a checkbox displayed below other fields. If nil, the checkbox is not displayed. + * The label of a checkbox displayed below other fields. If null, the checkbox is not displayed. * Defaults to null */ val checkboxLabel: String? = null @@ -121,7 +121,7 @@ internal class AddressLauncher internal constructor( */ class Builder { var appearance: PaymentSheet.Appearance = PaymentSheet.Appearance() - var defaultValues: AddressDetails? = null + var defaultValues: DefaultAddressDetails? = null var allowedCountries: Set = emptySet() var buttonTitle: String? = null var phone: AdditionalFieldsConfiguration = AdditionalFieldsConfiguration.OPTIONAL @@ -132,7 +132,7 @@ internal class AddressLauncher internal constructor( fun appearance(appearance: PaymentSheet.Appearance) = apply { this.appearance = appearance } - fun defaultValues(defaultValues: AddressDetails?) = + fun defaultValues(defaultValues: DefaultAddressDetails?) = apply { this.defaultValues = defaultValues } fun allowedCountries(allowedCountries: Set) = @@ -183,4 +183,28 @@ internal class AddressLauncher internal constructor( */ REQUIRED } + + @Parcelize + data class DefaultAddressDetails( + /** + * The customer's full name + */ + val name: String? = null, + + /** + * The customer's address + */ + val address: PaymentSheet.Address? = null, + + /** + * The customer's phone number, without formatting e.g. "5551234567" + */ + val phoneNumber: String? = null, + + /** + * Whether or not your custom checkbox is intially selected. + * Note: The checkbox is displayed below the other fields when AdditionalFieldsConfiguration.checkboxLabel is set. + */ + val isCheckboxSelected: Boolean? = null + ) : Parcelable } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressLauncherResult.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressLauncherResult.kt index 55a7ab212d4..388b3d94d47 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressLauncherResult.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressLauncherResult.kt @@ -12,15 +12,9 @@ internal sealed class AddressLauncherResult( ) : Parcelable { @Parcelize data class Succeeded( - // TODO add the real return type here once we iron it out. val address: AddressDetails ) : AddressLauncherResult(Activity.RESULT_OK) - @Parcelize - data class Failed( - val error: Throwable - ) : AddressLauncherResult(Activity.RESULT_CANCELED) - @Parcelize object Canceled : AddressLauncherResult(Activity.RESULT_CANCELED) diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressUtils.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressUtils.kt index 04e80fb14ce..c929f8a7116 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressUtils.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressUtils.kt @@ -38,11 +38,12 @@ fun CharSequence.levenshtein(other: CharSequence): Int { internal fun AddressDetails.editDistance(otherAddress: AddressDetails?): Int { var editDistance = 0 - editDistance += (city ?: "").levenshtein(otherAddress?.city ?: "") - editDistance += (country ?: "").levenshtein(otherAddress?.country ?: "") - editDistance += (line1 ?: "").levenshtein(otherAddress?.line1 ?: "") - editDistance += (line2 ?: "").levenshtein(otherAddress?.line2 ?: "") - editDistance += (postalCode ?: "").levenshtein(otherAddress?.postalCode ?: "") - editDistance += (state ?: "").levenshtein(otherAddress?.state ?: "") + val comparedAddress = otherAddress?.address + editDistance += (address?.city ?: "").levenshtein(comparedAddress?.city ?: "") + editDistance += (address?.country ?: "").levenshtein(comparedAddress?.country ?: "") + editDistance += (address?.line1 ?: "").levenshtein(comparedAddress?.line1 ?: "") + editDistance += (address?.line2 ?: "").levenshtein(comparedAddress?.line2 ?: "") + editDistance += (address?.postalCode ?: "").levenshtein(comparedAddress?.postalCode ?: "") + editDistance += (address?.state ?: "").levenshtein(comparedAddress?.state ?: "") return editDistance } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AutocompleteViewModel.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AutocompleteViewModel.kt index 049953cd93f..5ae1be2bd03 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AutocompleteViewModel.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AutocompleteViewModel.kt @@ -6,6 +6,7 @@ import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope +import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.R import com.stripe.android.paymentsheet.addresselement.analytics.AddressLauncherEventReporter import com.stripe.android.ui.core.injection.NonFallbackInjectable @@ -121,12 +122,14 @@ internal class AutocompleteViewModel @Inject constructor( val address = it.place.transformGoogleToStripeAddress(getApplication()) addressResult.value = Result.success( AddressDetails( - city = address.city, - country = address.country, - line1 = address.line1, - line2 = address.line2, - postalCode = address.postalCode, - state = address.state + address = PaymentSheet.Address( + city = address.city, + country = address.country, + line1 = address.line1, + line2 = address.line2, + postalCode = address.postalCode, + state = address.state + ) ) ) setResultAndGoBack() @@ -143,7 +146,9 @@ internal class AutocompleteViewModel @Inject constructor( fun onBackPressed() { val result = if (queryFlow.value.isNotBlank()) { AddressDetails( - line1 = queryFlow.value + address = PaymentSheet.Address( + line1 = queryFlow.value + ) ) } else { null @@ -154,7 +159,9 @@ internal class AutocompleteViewModel @Inject constructor( fun onEnterAddressManually() { setResultAndGoBack( AddressDetails( - line1 = queryFlow.value + address = PaymentSheet.Address( + line1 = queryFlow.value + ) ) ) } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModel.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModel.kt index b238fbaf62d..75b87ae9cde 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModel.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModel.kt @@ -4,6 +4,7 @@ import androidx.annotation.VisibleForTesting import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope +import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.addresselement.analytics.AddressLauncherEventReporter import com.stripe.android.ui.core.injection.NonFallbackInjectable import com.stripe.android.paymentsheet.injection.InputAddressViewModelSubcomponent @@ -29,7 +30,7 @@ internal class InputAddressViewModel @Inject constructor( private val eventReporter: AddressLauncherEventReporter, formControllerProvider: Provider ) : ViewModel() { - private val _collectedAddress = MutableStateFlow(args.config?.defaultValues) + private val _collectedAddress = MutableStateFlow(args.config?.defaultValues?.toAddressDetails()) val collectedAddress: StateFlow = _collectedAddress private val _formController = MutableStateFlow(null) @@ -44,34 +45,37 @@ internal class InputAddressViewModel @Inject constructor( init { viewModelScope.launch { navigator.getResultFlow(AddressDetails.KEY)?.collect { - val oldShippingAddress = _collectedAddress.value + val oldAddress = _collectedAddress.value val autocompleteAddress = AddressDetails( - name = oldShippingAddress?.name ?: it?.name, - company = oldShippingAddress?.company ?: it?.company, - phoneNumber = oldShippingAddress?.phoneNumber ?: it?.phoneNumber, - city = it?.city, - country = it?.country, - line1 = it?.line1, - line2 = it?.line2, - state = it?.state, - postalCode = it?.postalCode + name = oldAddress?.name ?: it?.name, + address = oldAddress?.address?.copy( + city = oldAddress.address.city ?: it?.address?.city, + country = oldAddress.address.country ?: it?.address?.country, + line1 = oldAddress.address.line1 ?: it?.address?.line1, + line2 = oldAddress.address.line2 ?: it?.address?.line2, + postalCode = oldAddress.address.postalCode ?: it?.address?.postalCode, + state = oldAddress.address.state ?: it?.address?.state + ) ?: it?.address, + phoneNumber = oldAddress?.phoneNumber ?: it?.phoneNumber, + isCheckboxSelected = oldAddress?.isCheckboxSelected + ?: it?.isCheckboxSelected ) _collectedAddress.emit(autocompleteAddress) } } viewModelScope.launch { - collectedAddress.collect { shippingAddress -> - val initialValues: Map = shippingAddress?.let { + collectedAddress.collect { addressDetails -> + val initialValues: Map = addressDetails?.let { mapOf( - IdentifierSpec.Name to shippingAddress.name, - IdentifierSpec.Line1 to shippingAddress.line1, - IdentifierSpec.Line2 to shippingAddress.line2, - IdentifierSpec.City to shippingAddress.city, - IdentifierSpec.State to shippingAddress.state, - IdentifierSpec.PostalCode to shippingAddress.postalCode, - IdentifierSpec.Country to shippingAddress.country, - IdentifierSpec.Phone to shippingAddress.phoneNumber + IdentifierSpec.Name to addressDetails.name, + IdentifierSpec.Line1 to addressDetails.address?.line1, + IdentifierSpec.Line2 to addressDetails.address?.line2, + IdentifierSpec.City to addressDetails.address?.city, + IdentifierSpec.State to addressDetails.address?.state, + IdentifierSpec.PostalCode to addressDetails.address?.postalCode, + IdentifierSpec.Country to addressDetails.address?.country, + IdentifierSpec.Phone to addressDetails.phoneNumber ) } ?: emptyMap() @@ -80,14 +84,14 @@ internal class InputAddressViewModel @Inject constructor( .viewModelScope(viewModelScope) .stripeIntent(null) .merchantName("") - .formSpec(buildFormSpec(shippingAddress?.line1 == null)) + .formSpec(buildFormSpec(addressDetails?.address?.line1 == null)) .initialValues(initialValues) .build().formController } } // allows merchants to check the box by default and to restore the value later. - args.config?.defaultValues?.checkboxChecked?.let { + args.config?.defaultValues?.isCheckboxSelected?.let { _checkboxChecked.value = it } } @@ -100,12 +104,14 @@ internal class InputAddressViewModel @Inject constructor( ?.let { AddressDetails( name = it[IdentifierSpec.Name]?.value, - city = it[IdentifierSpec.City]?.value, - country = it[IdentifierSpec.Country]?.value, - line1 = it[IdentifierSpec.Line1]?.value, - line2 = it[IdentifierSpec.Line2]?.value, - postalCode = it[IdentifierSpec.PostalCode]?.value, - state = it[IdentifierSpec.State]?.value, + address = PaymentSheet.Address( + city = it[IdentifierSpec.City]?.value, + country = it[IdentifierSpec.Country]?.value, + line1 = it[IdentifierSpec.Line1]?.value, + line2 = it[IdentifierSpec.Line2]?.value, + postalCode = it[IdentifierSpec.PostalCode]?.value, + state = it[IdentifierSpec.State]?.value + ), phoneNumber = it[IdentifierSpec.Phone]?.value ) } @@ -121,11 +127,11 @@ internal class InputAddressViewModel @Inject constructor( phoneNumberState = phoneNumberState ) { viewModelScope.launch { - val address = getCurrentAddress() - address?.let { + val addressDetails = getCurrentAddress() + addressDetails?.let { _collectedAddress.emit(it) } - address?.country?.let { + addressDetails?.address?.country?.let { navigator.navigateTo( AddressElementScreen.Autocomplete( country = it @@ -163,29 +169,31 @@ internal class InputAddressViewModel @Inject constructor( dismissWithAddress( AddressDetails( name = completedFormValues?.get(IdentifierSpec.Name)?.value, - city = completedFormValues?.get(IdentifierSpec.City)?.value, - country = completedFormValues?.get(IdentifierSpec.Country)?.value, - line1 = completedFormValues?.get(IdentifierSpec.Line1)?.value, - line2 = completedFormValues?.get(IdentifierSpec.Line2)?.value, - postalCode = completedFormValues?.get(IdentifierSpec.PostalCode)?.value, - state = completedFormValues?.get(IdentifierSpec.State)?.value, + address = PaymentSheet.Address( + city = completedFormValues?.get(IdentifierSpec.City)?.value, + country = completedFormValues?.get(IdentifierSpec.Country)?.value, + line1 = completedFormValues?.get(IdentifierSpec.Line1)?.value, + line2 = completedFormValues?.get(IdentifierSpec.Line2)?.value, + postalCode = completedFormValues?.get(IdentifierSpec.PostalCode)?.value, + state = completedFormValues?.get(IdentifierSpec.State)?.value + ), phoneNumber = completedFormValues?.get(IdentifierSpec.Phone)?.value, - checkboxChecked = checkboxChecked + isCheckboxSelected = checkboxChecked ) ) } @VisibleForTesting - fun dismissWithAddress(address: AddressDetails) { - address.country?.let { country -> + fun dismissWithAddress(addressDetails: AddressDetails) { + addressDetails.address?.country?.let { country -> eventReporter.onCompleted( country = country, - autocompleteResultSelected = collectedAddress.value?.line1 != null, - editDistance = address.editDistance(collectedAddress.value) + autocompleteResultSelected = collectedAddress.value?.address?.line1 != null, + editDistance = addressDetails.editDistance(collectedAddress.value) ) } navigator.dismiss( - AddressLauncherResult.Succeeded(address) + AddressLauncherResult.Succeeded(addressDetails) ) } diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/AddressUtilsTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/AddressUtilsTest.kt index a4841178427..deadeeba70f 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/AddressUtilsTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/AddressUtilsTest.kt @@ -1,6 +1,7 @@ package com.stripe.android.paymentsheet.addresselement import com.google.common.truth.Truth +import com.stripe.android.paymentsheet.PaymentSheet import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner @@ -10,11 +11,13 @@ class AddressUtilsTest { @Test fun `test edit distance equal address`() { val address = AddressDetails( - city = "San Francisco", - country = "AT", - line1 = "510 Townsend St.", - postalCode = "94102", - state = "California" + address = PaymentSheet.Address( + city = "San Francisco", + country = "AT", + line1 = "510 Townsend St.", + postalCode = "94102", + state = "California" + ) ) Truth.assertThat(address.editDistance(address)).isEqualTo(0) @@ -23,19 +26,23 @@ class AddressUtilsTest { @Test fun `test edit distance one char diff`() { val address = AddressDetails( - city = "San Francisco", - country = "AT", - line1 = "510 Townsend St.", - postalCode = "94102", - state = "California" + address = PaymentSheet.Address( + city = "San Francisco", + country = "AT", + line1 = "510 Townsend St.", + postalCode = "94102", + state = "California" + ) ) val otherAddress = AddressDetails( - city = "Sa Francisco", // One char diff here - country = "AT", - line1 = "510 Townsend St.", - postalCode = "94102", - state = "California" + address = PaymentSheet.Address( + city = "Sa Francisco", // One char diff here + country = "AT", + line1 = "510 Townsend St.", + postalCode = "94102", + state = "California" + ) ) Truth.assertThat(address.editDistance(otherAddress)).isEqualTo(1) @@ -44,19 +51,23 @@ class AddressUtilsTest { @Test fun `test edit distance different city`() { val address = AddressDetails( - city = "San Francisco", - country = "AT", - line1 = "510 Townsend St.", - postalCode = "94102", - state = "California" + address = PaymentSheet.Address( + city = "San Francisco", + country = "AT", + line1 = "510 Townsend St.", + postalCode = "94102", + state = "California" + ) ) val otherAddress = AddressDetails( - city = "Freemont", - country = "AT", - line1 = "510 Townsend St.", - postalCode = "94102", - state = "California" + address = PaymentSheet.Address( + city = "Freemont", + country = "AT", + line1 = "510 Townsend St.", + postalCode = "94102", + state = "California" + ) ) Truth.assertThat(address.editDistance(otherAddress)).isEqualTo(11) @@ -65,19 +76,23 @@ class AddressUtilsTest { @Test fun `test edit distance missing city original`() { val address = AddressDetails( - city = null, - country = "AT", - line1 = "510 Townsend St.", - postalCode = "94102", - state = "California" + address = PaymentSheet.Address( + city = null, + country = "AT", + line1 = "510 Townsend St.", + postalCode = "94102", + state = "California" + ) ) val otherAddress = AddressDetails( - city = "San Francisco", - country = "AT", - line1 = "510 Townsend St.", - postalCode = "94102", - state = "California" + address = PaymentSheet.Address( + city = "San Francisco", + country = "AT", + line1 = "510 Townsend St.", + postalCode = "94102", + state = "California" + ) ) Truth.assertThat(address.editDistance(otherAddress)).isEqualTo(13) @@ -86,19 +101,23 @@ class AddressUtilsTest { @Test fun `test edit distance missing city other`() { val address = AddressDetails( - city = "San Francisco", - country = "AT", - line1 = "510 Townsend St.", - postalCode = "94102", - state = "California" + address = PaymentSheet.Address( + city = "San Francisco", + country = "AT", + line1 = "510 Townsend St.", + postalCode = "94102", + state = "California" + ) ) val otherAddress = AddressDetails( - city = null, - country = "AT", - line1 = "510 Townsend St.", - postalCode = "94102", - state = "California" + address = PaymentSheet.Address( + city = null, + country = "AT", + line1 = "510 Townsend St.", + postalCode = "94102", + state = "California" + ) ) Truth.assertThat(address.editDistance(otherAddress)).isEqualTo(13) diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/AutocompleteViewModelTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/AutocompleteViewModelTest.kt index 7ebd0f9bed8..49ee523f4d9 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/AutocompleteViewModelTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/AutocompleteViewModelTest.kt @@ -5,6 +5,7 @@ import android.text.SpannableString import androidx.lifecycle.viewModelScope import androidx.test.core.app.ApplicationProvider import com.google.common.truth.Truth.assertThat +import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.addresselement.analytics.AddressLauncherEventReporter import com.stripe.android.ui.core.elements.TextFieldIcon import com.stripe.android.ui.core.elements.autocomplete.PlacesClientProxy @@ -77,12 +78,14 @@ class AutocompleteViewModelTest { ) val expectedResult = Result.success( AddressDetails( - city = null, - country = null, - line1 = "", - line2 = null, - postalCode = null, - state = null + address = PaymentSheet.Address( + city = null, + country = null, + line1 = "", + line2 = null, + postalCode = null, + state = null + ) ) ) whenever(mockClient.fetchPlace(any())).thenReturn(fetchPlaceResponse) @@ -134,7 +137,9 @@ class AutocompleteViewModelTest { val viewModel = createViewModel() val expectedResult = Result.success( AddressDetails( - line1 = "Some query" + address = PaymentSheet.Address( + line1 = "Some query" + ) ) ) @@ -150,7 +155,9 @@ class AutocompleteViewModelTest { val viewModel = createViewModel() val expectedResult = Result.success( AddressDetails( - line1 = "" + address = PaymentSheet.Address( + line1 = "" + ) ) ) @@ -229,7 +236,10 @@ class AutocompleteViewModelTest { viewModel.textFieldController.onRawValueChange("a") viewModel.onBackPressed() - verify(viewModel.navigator).setResult(eq(AddressDetails.KEY), eq(AddressDetails(line1 = "a"))) + verify(viewModel.navigator).setResult( + eq(AddressDetails.KEY), + eq(AddressDetails(address = PaymentSheet.Address(line1 = "a"))) + ) } @Test diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModelTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModelTest.kt index 896a4920bcf..23e8580bf5d 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModelTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModelTest.kt @@ -1,6 +1,7 @@ package com.stripe.android.paymentsheet.addresselement import com.google.common.truth.Truth.assertThat +import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.addresselement.analytics.AddressLauncherEventReporter import com.stripe.android.ui.core.injection.FormControllerSubcomponent import kotlinx.coroutines.Dispatchers @@ -45,7 +46,7 @@ class InputAddressViewModelTest { } private val eventReporter = mock() - private fun createViewModel(defaultAddress: AddressDetails? = null): InputAddressViewModel { + private fun createViewModel(defaultAddress: AddressLauncher.DefaultAddressDetails? = null): InputAddressViewModel { defaultAddress?.let { whenever(config.defaultValues).thenReturn(defaultAddress) } @@ -79,7 +80,7 @@ class InputAddressViewModelTest { @Test fun `autocomplete address passed is collected to start`() = runTest(UnconfinedTestDispatcher()) { - val expectedAddress = AddressDetails(name = "skyler", company = "stripe") + val expectedAddress = AddressDetails(name = "skyler", address = PaymentSheet.Address(country = "US")) val flow = MutableStateFlow(expectedAddress) whenever(navigator.getResultFlow(any())).thenReturn(flow) @@ -89,26 +90,30 @@ class InputAddressViewModelTest { @Test fun `default address from merchant is parsed`() = runTest(UnconfinedTestDispatcher()) { - val expectedAddress = AddressDetails(name = "skyler", company = "stripe") + val expectedAddress = AddressLauncher.DefaultAddressDetails(name = "skyler", address = PaymentSheet.Address(country = "US")) val viewModel = createViewModel(expectedAddress) - assertThat(viewModel.collectedAddress.value).isEqualTo(expectedAddress) + assertThat(viewModel.collectedAddress.value).isEqualTo(expectedAddress.toAddressDetails()) } @Test fun `viewModel emits onComplete event`() = runTest(UnconfinedTestDispatcher()) { val viewModel = createViewModel( - AddressDetails( - line1 = "99 Broadway St", - city = "Seattle", - country = "US" + AddressLauncher.DefaultAddressDetails( + address = PaymentSheet.Address( + line1 = "99 Broadway St", + city = "Seattle", + country = "US" + ) ) ) viewModel.dismissWithAddress( AddressDetails( - line1 = "99 Broadway St", - city = "Seattle", - country = "US" + address = PaymentSheet.Address( + line1 = "99 Broadway St", + city = "Seattle", + country = "US" + ) ) ) verify(eventReporter).onCompleted( @@ -121,8 +126,8 @@ class InputAddressViewModelTest { @Test fun `default checkbox should emit true to start if passed by merchant`() = runTest(UnconfinedTestDispatcher()) { val viewModel = createViewModel( - AddressDetails( - checkboxChecked = true + AddressLauncher.DefaultAddressDetails( + isCheckboxSelected = true ) ) assertThat(viewModel.checkboxChecked.value).isTrue() @@ -131,8 +136,8 @@ class InputAddressViewModelTest { @Test fun `default checkbox should emit false to start if passed by merchant`() = runTest(UnconfinedTestDispatcher()) { val viewModel = createViewModel( - AddressDetails( - checkboxChecked = false + AddressLauncher.DefaultAddressDetails( + isCheckboxSelected = false ) ) assertThat(viewModel.checkboxChecked.value).isFalse()