mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-19 09:25:34 +00:00
[fenix] fixes https://github.com/mozilla-mobile/fenix/issues/24918: add subregion dropdown to address editor
This commit is contained in:
parent
e175c84def
commit
d081128be7
@ -0,0 +1,158 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.settings.address
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import mozilla.components.concept.storage.Address
|
||||
import org.mozilla.fenix.R
|
||||
|
||||
internal const val DEFAULT_COUNTRY = "US"
|
||||
|
||||
/**
|
||||
* Value type representing properties determined by the country used in an [Address].
|
||||
* This data is meant to mirror the data currently represented on desktop here:
|
||||
* https://searchfox.org/mozilla-central/source/toolkit/components/formautofill/addressmetadata/addressReferences.js
|
||||
*
|
||||
* This can be expanded to included things like a list of applicable states/provinces per country
|
||||
* or the names that should be used for each form field.
|
||||
*
|
||||
* Note: Most properties here need to be kept in sync with the data in the above desktop
|
||||
* address reference file in order to prevent duplications when sync is enabled. There are
|
||||
* ongoing conversations about how best to share that data cross-platform, if at all.
|
||||
* Some more detail: https://bugzilla.mozilla.org/show_bug.cgi?id=1769809
|
||||
*
|
||||
* Exceptions: [displayName] is a local property and stop-gap to a more robust solution.
|
||||
*
|
||||
* @property countryCode The country code used to lookup the address data. Should match desktop entries.
|
||||
* @property displayName The name to display when selected.
|
||||
*/
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
internal data class Country(
|
||||
val countryCode: String,
|
||||
val displayName: String,
|
||||
@StringRes val subregionTitleResource: Int,
|
||||
val subregions: List<String>,
|
||||
)
|
||||
|
||||
internal object AddressUtils {
|
||||
/**
|
||||
* The current list of supported countries.
|
||||
*/
|
||||
val countries = mapOf(
|
||||
"CA" to Country(
|
||||
countryCode = "CA",
|
||||
displayName = "Canada",
|
||||
subregionTitleResource = R.string.addresses_province,
|
||||
subregions = Subregions.CA,
|
||||
),
|
||||
"US" to Country(
|
||||
countryCode = "US",
|
||||
displayName = "United States",
|
||||
subregionTitleResource = R.string.addresses_state,
|
||||
subregions = Subregions.US,
|
||||
),
|
||||
)
|
||||
|
||||
/**
|
||||
* Get the country code associated with a [Country.displayName], or the [DEFAULT_COUNTRY] code
|
||||
* if the display name is not supported.
|
||||
*/
|
||||
fun getCountryCode(displayName: String) = countries.values.find {
|
||||
it.displayName == displayName
|
||||
}?.countryCode ?: DEFAULT_COUNTRY
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a [Country.displayName] to the associated country code.
|
||||
*/
|
||||
fun String.toCountryCode() = AddressUtils.getCountryCode(this)
|
||||
|
||||
private object Subregions {
|
||||
// This data is meant to mirror the data currently represented on desktop here:
|
||||
// https://searchfox.org/mozilla-central/source/toolkit/components/formautofill/addressmetadata/addressReferences.js
|
||||
val CA = listOf(
|
||||
"Alberta",
|
||||
"British Columbia",
|
||||
"Manitoba",
|
||||
"New Brunswick",
|
||||
"Newfoundland and Labrador",
|
||||
"Northwest Territories",
|
||||
"Nova Scotia",
|
||||
"Nunavut",
|
||||
"Ontario",
|
||||
"Prince Edward Island",
|
||||
"Quebec",
|
||||
"Saskatchewan",
|
||||
"Yukon",
|
||||
)
|
||||
|
||||
// This data is meant to mirror the data currently represented on desktop here:
|
||||
// https://searchfox.org/mozilla-central/source/toolkit/components/formautofill/addressmetadata/addressReferences.js
|
||||
val US = listOf(
|
||||
"Alabama",
|
||||
"Alaska",
|
||||
"American Samoa",
|
||||
"Arizona",
|
||||
"Arkansas",
|
||||
"Armed Forces (AA)",
|
||||
"Armed Forces (AE)",
|
||||
"Armed Forces (AP)",
|
||||
"California",
|
||||
"Colorado",
|
||||
"Connecticut",
|
||||
"Delaware",
|
||||
"District of Columbia",
|
||||
"Florida",
|
||||
"Georgia",
|
||||
"Guam",
|
||||
"Hawaii",
|
||||
"Idaho",
|
||||
"Illinois",
|
||||
"Indiana",
|
||||
"Iowa",
|
||||
"Kansas",
|
||||
"Kentucky",
|
||||
"Louisiana",
|
||||
"Maine",
|
||||
"Marshall Islands",
|
||||
"Maryland",
|
||||
"Massachusetts",
|
||||
"Michigan",
|
||||
"Micronesia",
|
||||
"Minnesota",
|
||||
"Mississippi",
|
||||
"Missouri",
|
||||
"Montana",
|
||||
"Nebraska",
|
||||
"Nevada",
|
||||
"New Hampshire",
|
||||
"New Jersey",
|
||||
"New Mexico",
|
||||
"New York",
|
||||
"North Carolina",
|
||||
"North Dakota",
|
||||
"Northern Mariana Islands",
|
||||
"Ohio",
|
||||
"Oklahoma",
|
||||
"Oregon",
|
||||
"Palau",
|
||||
"Pennsylvania",
|
||||
"Puerto Rico",
|
||||
"Rhode Island",
|
||||
"South Carolina",
|
||||
"South Dakota",
|
||||
"Tennessee",
|
||||
"Texas",
|
||||
"Utah",
|
||||
"Vermont",
|
||||
"Virgin Islands",
|
||||
"Virginia",
|
||||
"Washington",
|
||||
"West Virginia",
|
||||
"Wisconsin",
|
||||
"Wyoming",
|
||||
)
|
||||
}
|
@ -6,11 +6,12 @@ package org.mozilla.fenix.settings.address.view
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import mozilla.components.concept.storage.Address
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import mozilla.components.browser.state.search.RegionState
|
||||
import mozilla.components.concept.storage.UpdatableAddressFields
|
||||
import mozilla.components.support.ktx.android.view.hideKeyboard
|
||||
@ -19,12 +20,19 @@ import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.databinding.FragmentAddressEditorBinding
|
||||
import org.mozilla.fenix.ext.placeCursorAtEnd
|
||||
import org.mozilla.fenix.settings.address.AddressEditorFragment
|
||||
import org.mozilla.fenix.settings.address.AddressUtils.countries
|
||||
import org.mozilla.fenix.settings.address.Country
|
||||
import org.mozilla.fenix.settings.address.DEFAULT_COUNTRY
|
||||
import org.mozilla.fenix.settings.address.interactor.AddressEditorInteractor
|
||||
|
||||
internal const val DEFAULT_COUNTRY = "US"
|
||||
import org.mozilla.fenix.settings.address.toCountryCode
|
||||
|
||||
/**
|
||||
* Shows an address editor for adding or updating an address.
|
||||
* An address editor for adding or updating an address.
|
||||
*
|
||||
* @param binding The binding used to display the view.
|
||||
* @param interactor [AddressEditorInteractor] used to respond to any user interactions.
|
||||
* @param region If the [RegionState] is available, it will be used to set the country when adding a new address.
|
||||
* @param address An [Address] to edit.
|
||||
*/
|
||||
class AddressEditorView(
|
||||
private val binding: FragmentAddressEditorBinding,
|
||||
@ -33,36 +41,6 @@ class AddressEditorView(
|
||||
private val address: Address? = null
|
||||
) {
|
||||
|
||||
/**
|
||||
* Value type representing properties determined by the country used in an [Address].
|
||||
* This data is meant to mirror the data currently represented on desktop here:
|
||||
* https://searchfox.org/mozilla-central/source/toolkit/components/formautofill/addressmetadata/addressReferences.js
|
||||
*
|
||||
* This can be expanded to included things like a list of applicable states/provinces per country
|
||||
* or the names that should be used for each form field.
|
||||
*
|
||||
* Note: Most properties here need to be kept in sync with the data in the above desktop
|
||||
* address reference file in order to prevent duplications when sync is enabled. There are
|
||||
* ongoing conversations about how best to share that data cross-platform, if at all.
|
||||
* Some more detail: https://bugzilla.mozilla.org/show_bug.cgi?id=1769809
|
||||
*
|
||||
* Exceptions: [displayName] is a local property and stop-gap to a more robust solution.
|
||||
*
|
||||
* @property key The country code used to lookup the address data. Should match desktop entries.
|
||||
* @property displayName The name to display when selected.
|
||||
*/
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
internal data class Country(
|
||||
val key: String,
|
||||
val displayName: String,
|
||||
)
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
internal val countries = mapOf(
|
||||
"CA" to Country("CA", "Canada"),
|
||||
"US" to Country("US", "United States"),
|
||||
)
|
||||
|
||||
/**
|
||||
* Binds the view in the [AddressEditorFragment], using the current [Address] if available.
|
||||
*/
|
||||
@ -91,7 +69,6 @@ class AddressEditorView(
|
||||
|
||||
binding.streetAddressInput.setText(address.streetAddress)
|
||||
binding.cityInput.setText(address.addressLevel2)
|
||||
binding.stateInput.setText(address.addressLevel1)
|
||||
binding.zipInput.setText(address.postalCode)
|
||||
|
||||
binding.deleteButton.apply {
|
||||
@ -102,7 +79,7 @@ class AddressEditorView(
|
||||
}
|
||||
}
|
||||
|
||||
bindCountryDropdown()
|
||||
bindDropdowns()
|
||||
}
|
||||
|
||||
internal fun saveAddress() {
|
||||
@ -116,7 +93,7 @@ class AddressEditorView(
|
||||
streetAddress = binding.streetAddressInput.text.toString(),
|
||||
addressLevel3 = "",
|
||||
addressLevel2 = "",
|
||||
addressLevel1 = "",
|
||||
addressLevel1 = binding.subregionDropDown.selectedItem.toString(),
|
||||
postalCode = binding.zipInput.text.toString(),
|
||||
country = binding.countryDropDown.selectedItem.toString().toCountryCode(),
|
||||
tel = binding.phoneInput.text.toString(),
|
||||
@ -143,26 +120,59 @@ class AddressEditorView(
|
||||
}.show()
|
||||
}
|
||||
|
||||
private fun bindCountryDropdown() {
|
||||
val adapter = ArrayAdapter<String>(
|
||||
private fun bindDropdowns() {
|
||||
val adapter = ArrayAdapter(
|
||||
binding.root.context,
|
||||
android.R.layout.simple_spinner_dropdown_item,
|
||||
countries.values.map { it.displayName }
|
||||
)
|
||||
|
||||
val selectedCountryKey = (address?.country ?: region?.home).takeIf {
|
||||
it in countries.keys
|
||||
} ?: DEFAULT_COUNTRY
|
||||
var selectedPosition = -1
|
||||
countries.values.forEachIndexed { index, country ->
|
||||
if (country.key == selectedCountryKey) selectedPosition = index
|
||||
adapter.add(country.displayName)
|
||||
}
|
||||
|
||||
val selectedPosition = countries.values
|
||||
.indexOfFirst { it.countryCode == selectedCountryKey }
|
||||
.takeIf { it > 0 }
|
||||
?: 0
|
||||
|
||||
binding.countryDropDown.adapter = adapter
|
||||
binding.countryDropDown.setSelection(selectedPosition)
|
||||
binding.countryDropDown.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(
|
||||
parent: AdapterView<*>?,
|
||||
view: View?,
|
||||
position: Int,
|
||||
id: Long
|
||||
) {
|
||||
val newCountryKey = binding.countryDropDown.selectedItem.toString().toCountryCode()
|
||||
countries[newCountryKey]?.let { country ->
|
||||
bindSubregionDropdown(country)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNothingSelected(p0: AdapterView<*>?) = Unit
|
||||
}
|
||||
|
||||
countries[selectedCountryKey]?.let { country ->
|
||||
bindSubregionDropdown(country)
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.toCountryCode() = countries.values.find {
|
||||
it.displayName == this
|
||||
}?.key ?: DEFAULT_COUNTRY
|
||||
private fun bindSubregionDropdown(country: Country) {
|
||||
val subregions = country.subregions
|
||||
val selectedSubregion = address?.addressLevel1?.takeIf { it in subregions }
|
||||
?: subregions.first()
|
||||
|
||||
val adapter = ArrayAdapter(
|
||||
binding.root.context,
|
||||
android.R.layout.simple_spinner_dropdown_item,
|
||||
country.subregions
|
||||
)
|
||||
|
||||
val selectedPosition = subregions.indexOf(selectedSubregion).takeIf { it > 0 } ?: 0
|
||||
binding.subregionDropDown.adapter = adapter
|
||||
binding.subregionDropDown.setSelection(selectedPosition)
|
||||
binding.subregionTitle.setText(country.subregionTitleResource)
|
||||
}
|
||||
}
|
||||
|
@ -234,50 +234,40 @@
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<!-- State -->
|
||||
<TextView
|
||||
android:id="@+id/state_title"
|
||||
android:layout_width="wrap_content"
|
||||
<!-- Subregion -->
|
||||
<LinearLayout
|
||||
android:id="@+id/subregion_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical"
|
||||
android:letterSpacing="0.05"
|
||||
android:paddingStart="3dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:text="@string/addresses_state"
|
||||
android:textColor="?attr/textPrimary"
|
||||
android:textSize="12sp"
|
||||
android:labelFor="@id/state_input"
|
||||
app:fontFamily="@font/metropolis_semibold"
|
||||
android:paddingEnd="3dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/city_layout" />
|
||||
app:layout_constraintTop_toBottomOf="@id/city_layout"
|
||||
app:layout_constraintBottom_toTopOf="@id/zip_title">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/state_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/textPrimary"
|
||||
app:hintEnabled="false"
|
||||
app:layout_constraintHorizontal_bias="0.8"
|
||||
app:layout_constraintEnd_toStartOf="@+id/zip_layout"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/state_title">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/state_input"
|
||||
android:layout_width="match_parent"
|
||||
<TextView
|
||||
android:id="@+id/subregion_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:fontFamily="sans-serif"
|
||||
android:imeOptions="flagNoExtractUi"
|
||||
android:letterSpacing="0.01"
|
||||
android:lineSpacingExtra="8sp"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:layout_marginTop="10dp"
|
||||
android:textColor="?attr/textPrimary"
|
||||
android:textSize="16sp" />
|
||||
android:textSize="12sp"
|
||||
android:labelFor="@id/subregion_drop_down"
|
||||
app:fontFamily="@font/metropolis_semibold"
|
||||
android:text="@string/addresses_state" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/subregion_drop_down"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/textPrimary" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Zip -->
|
||||
<TextView
|
||||
@ -295,17 +285,16 @@
|
||||
android:labelFor="@id/zip_input"
|
||||
app:fontFamily="@font/metropolis_semibold"
|
||||
app:layout_constraintStart_toStartOf="@+id/zip_layout"
|
||||
app:layout_constraintTop_toBottomOf="@+id/city_layout" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/subregion_layout" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/zip_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:textColor="?attr/textPrimary"
|
||||
app:hintEnabled="false"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/state_layout"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/zip_title">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
@ -331,7 +320,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:paddingStart="3dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:paddingEnd="3dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
@ -341,6 +330,7 @@
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:textColor="?attr/textPrimary"
|
||||
android:textSize="12sp"
|
||||
android:labelFor="@id/country_drop_down"
|
||||
@ -487,7 +477,7 @@
|
||||
android:paddingEnd="12dp"
|
||||
android:text="@string/addresses_save_button"
|
||||
app:layout_constraintTop_toTopOf="@+id/cancel_button"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/cancel_button"
|
||||
app:layout_constraintBottom_toBottomOf="@id/cancel_button"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
@ -1567,8 +1567,10 @@
|
||||
<string name="addresses_street_address">Street Address</string>
|
||||
<!-- The header for the city of an address -->
|
||||
<string name="addresses_city">City</string>
|
||||
<!-- The header for the state of an address -->
|
||||
<!-- The header for the subregion of an address when "state" should be used -->
|
||||
<string name="addresses_state">State</string>
|
||||
<!-- The header for the subregion of an address when "province" should be used -->
|
||||
<string name="addresses_province">Province</string>
|
||||
<!-- The header for the zip code of an address -->
|
||||
<string name="addresses_zip">Zip</string>
|
||||
<!-- The header for the country or region of an address -->
|
||||
|
@ -13,8 +13,10 @@ import io.mockk.verify
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import mozilla.components.browser.state.search.RegionState
|
||||
import mozilla.components.concept.storage.Address
|
||||
import mozilla.components.concept.storage.UpdatableAddressFields
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@ -23,7 +25,6 @@ import org.mozilla.fenix.databinding.FragmentAddressEditorBinding
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import org.mozilla.fenix.settings.address.interactor.AddressEditorInteractor
|
||||
import org.mozilla.fenix.settings.address.view.AddressEditorView
|
||||
import org.mozilla.fenix.settings.address.view.DEFAULT_COUNTRY
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class AddressEditorViewTest {
|
||||
@ -45,6 +46,63 @@ class AddressEditorViewTest {
|
||||
addressEditorView = spyk(AddressEditorView(binding, interactor))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN an existing address WHEN the save button is clicked THEN interactor updates address`() {
|
||||
val country = AddressUtils.countries["US"]!!
|
||||
val address = generateAddress(country = country.countryCode, addressLevel1 = country.subregions[0])
|
||||
val addressEditorView = AddressEditorView(
|
||||
binding = binding,
|
||||
interactor = interactor,
|
||||
address = address,
|
||||
)
|
||||
|
||||
addressEditorView.bind()
|
||||
addressEditorView.saveAddress()
|
||||
|
||||
val expected = UpdatableAddressFields(
|
||||
givenName = address.givenName,
|
||||
additionalName = address.additionalName,
|
||||
familyName = address.familyName,
|
||||
organization = "",
|
||||
streetAddress = address.streetAddress,
|
||||
addressLevel3 = "",
|
||||
addressLevel2 = "",
|
||||
addressLevel1 = address.addressLevel1,
|
||||
postalCode = address.postalCode,
|
||||
country = address.country,
|
||||
tel = address.tel,
|
||||
email = address.email,
|
||||
)
|
||||
verify { interactor.onUpdateAddress(address.guid, expected) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN a new address WHEN the save button is clicked THEN interactor saves new address`() {
|
||||
val addressEditorView = AddressEditorView(
|
||||
binding = binding,
|
||||
interactor = interactor,
|
||||
)
|
||||
|
||||
addressEditorView.bind()
|
||||
addressEditorView.saveAddress()
|
||||
|
||||
val expected = UpdatableAddressFields(
|
||||
givenName = "",
|
||||
additionalName = "",
|
||||
familyName = "",
|
||||
organization = "",
|
||||
streetAddress = "",
|
||||
addressLevel3 = "",
|
||||
addressLevel2 = "",
|
||||
addressLevel1 = "Alabama",
|
||||
postalCode = "",
|
||||
country = "US",
|
||||
tel = "",
|
||||
email = "",
|
||||
)
|
||||
verify { interactor.onSaveAddress(expected) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN the cancel button is clicked THEN interactor is called`() {
|
||||
addressEditorView.bind()
|
||||
@ -68,7 +126,7 @@ class AddressEditorViewTest {
|
||||
addressEditorView.bind()
|
||||
|
||||
assertEquals("PostalCode", binding.zipInput.text.toString())
|
||||
assertEquals("State", binding.stateInput.text.toString())
|
||||
assertEquals(address.addressLevel1, binding.subregionDropDown.selectedItem.toString())
|
||||
assertEquals("City", binding.cityInput.text.toString())
|
||||
assertEquals("Street", binding.streetAddressInput.text.toString())
|
||||
assertEquals("Family", binding.lastNameInput.text.toString())
|
||||
@ -108,6 +166,72 @@ class AddressEditorViewTest {
|
||||
verify { addressEditorView.showConfirmDeleteAddressDialog(view.context, "123") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN existing address with correct subregion and country WHEN subregion dropdown is bound THEN adapter sets subregion dropdown to address`() {
|
||||
val address = generateAddress(country = "US", addressLevel1 = "Oregon")
|
||||
|
||||
val addressEditorView = AddressEditorView(
|
||||
binding = binding,
|
||||
interactor = interactor,
|
||||
address = address,
|
||||
)
|
||||
addressEditorView.bind()
|
||||
|
||||
assertEquals("Oregon", binding.subregionDropDown.selectedItem.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN existing address subregion outside of country WHEN subregion dropdown is bound THEN dropdown defaults to first subregion entry for country`() {
|
||||
val address = generateAddress(country = "CA", addressLevel1 = "Alabama")
|
||||
|
||||
val addressEditorView = AddressEditorView(
|
||||
binding = binding,
|
||||
interactor = interactor,
|
||||
address = address,
|
||||
)
|
||||
addressEditorView.bind()
|
||||
|
||||
assertEquals("Alberta", binding.subregionDropDown.selectedItem.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN no existing address WHEN subregion dropdown is bound THEN dropdown defaults to first subregion of default country`() {
|
||||
val addressEditorView = AddressEditorView(
|
||||
binding = binding,
|
||||
interactor = interactor,
|
||||
)
|
||||
addressEditorView.bind()
|
||||
|
||||
assertEquals("Alabama", binding.subregionDropDown.selectedItem.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN country is changed THEN available subregions are updated`() {
|
||||
val addressEditorView = AddressEditorView(
|
||||
binding = binding,
|
||||
interactor = interactor,
|
||||
)
|
||||
addressEditorView.bind()
|
||||
|
||||
assertEquals("Alabama", binding.subregionDropDown.selectedItem.toString())
|
||||
binding.countryDropDown.setSelection(0)
|
||||
assertNotEquals("Alabama", binding.subregionDropDown.selectedItem.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN existing address not in available countries WHEN view is bound THEN country and subregion dropdowns are set to default `() {
|
||||
val address = generateAddress(country = "I AM NOT A COUNTRY", addressLevel1 = "I AM NOT A STATE")
|
||||
val addressEditorView = AddressEditorView(
|
||||
binding = binding,
|
||||
interactor = interactor,
|
||||
address = address,
|
||||
)
|
||||
addressEditorView.bind()
|
||||
|
||||
assertEquals("United States", binding.countryDropDown.selectedItem.toString())
|
||||
assertEquals("Alabama", binding.subregionDropDown.selectedItem.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN existing address WHEN country dropdown is bound THEN adapter sets country dropdown to address`() {
|
||||
val addressEditorView = spyk(
|
||||
@ -119,7 +243,7 @@ class AddressEditorViewTest {
|
||||
)
|
||||
addressEditorView.bind()
|
||||
|
||||
assertEquals(addressEditorView.countries["CA"]?.displayName, binding.countryDropDown.selectedItem.toString())
|
||||
assertEquals(AddressUtils.countries["CA"]?.displayName, binding.countryDropDown.selectedItem.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -134,7 +258,7 @@ class AddressEditorViewTest {
|
||||
)
|
||||
addressEditorView.bind()
|
||||
|
||||
assertEquals(addressEditorView.countries[DEFAULT_COUNTRY]!!.displayName, binding.countryDropDown.selectedItem.toString())
|
||||
assertEquals(AddressUtils.countries[DEFAULT_COUNTRY]!!.displayName, binding.countryDropDown.selectedItem.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -147,7 +271,7 @@ class AddressEditorViewTest {
|
||||
)
|
||||
addressEditorView.bind()
|
||||
|
||||
assertEquals(addressEditorView.countries["CA"]?.displayName, binding.countryDropDown.selectedItem.toString())
|
||||
assertEquals(AddressUtils.countries["CA"]?.displayName, binding.countryDropDown.selectedItem.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -160,7 +284,7 @@ class AddressEditorViewTest {
|
||||
)
|
||||
addressEditorView.bind()
|
||||
|
||||
assertEquals(addressEditorView.countries[DEFAULT_COUNTRY]!!.displayName, binding.countryDropDown.selectedItem.toString())
|
||||
assertEquals(AddressUtils.countries[DEFAULT_COUNTRY]!!.displayName, binding.countryDropDown.selectedItem.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -173,10 +297,10 @@ class AddressEditorViewTest {
|
||||
)
|
||||
addressEditorView.bind()
|
||||
|
||||
assertEquals(addressEditorView.countries[DEFAULT_COUNTRY]!!.displayName, binding.countryDropDown.selectedItem.toString())
|
||||
assertEquals(AddressUtils.countries[DEFAULT_COUNTRY]!!.displayName, binding.countryDropDown.selectedItem.toString())
|
||||
}
|
||||
|
||||
private fun generateAddress(country: String = "US") = Address(
|
||||
private fun generateAddress(country: String = "US", addressLevel1: String = "Oregon") = Address(
|
||||
guid = "123",
|
||||
givenName = "Given",
|
||||
additionalName = "Additional",
|
||||
@ -185,7 +309,7 @@ class AddressEditorViewTest {
|
||||
streetAddress = "Street",
|
||||
addressLevel3 = "Suburb",
|
||||
addressLevel2 = "City",
|
||||
addressLevel1 = "State",
|
||||
addressLevel1 = addressLevel1,
|
||||
postalCode = "PostalCode",
|
||||
country = country,
|
||||
tel = "Telephone",
|
||||
|
Loading…
Reference in New Issue
Block a user