You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
347 lines
12 KiB
Kotlin
347 lines
12 KiB
Kotlin
/* 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 android.view.LayoutInflater
|
|
import android.view.View
|
|
import io.mockk.every
|
|
import io.mockk.mockk
|
|
import io.mockk.spyk
|
|
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.service.glean.testing.GleanTestRule
|
|
import mozilla.components.support.test.robolectric.testContext
|
|
import org.junit.Assert.assertEquals
|
|
import org.junit.Assert.assertNotEquals
|
|
import org.junit.Assert.assertNotNull
|
|
import org.junit.Assert.assertNull
|
|
import org.junit.Before
|
|
import org.junit.Rule
|
|
import org.junit.Test
|
|
import org.junit.runner.RunWith
|
|
import org.mozilla.fenix.GleanMetrics.Addresses
|
|
import org.mozilla.fenix.R
|
|
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
|
|
|
|
@RunWith(FenixRobolectricTestRunner::class) // For gleanTestRule
|
|
class AddressEditorViewTest {
|
|
|
|
private lateinit var view: View
|
|
private lateinit var interactor: AddressEditorInteractor
|
|
private lateinit var addressEditorView: AddressEditorView
|
|
private lateinit var binding: FragmentAddressEditorBinding
|
|
private lateinit var address: Address
|
|
|
|
@get:Rule
|
|
val gleanTestRule = GleanTestRule(testContext)
|
|
|
|
@Before
|
|
fun setup() {
|
|
view = LayoutInflater.from(testContext).inflate(R.layout.fragment_address_editor, null)
|
|
binding = FragmentAddressEditorBinding.bind(view)
|
|
interactor = mockk(relaxed = true)
|
|
address = mockk(relaxed = true)
|
|
every { address.guid } returns "123"
|
|
|
|
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(
|
|
name = address.name,
|
|
organization = "",
|
|
streetAddress = address.streetAddress,
|
|
addressLevel3 = "",
|
|
addressLevel2 = address.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(
|
|
name = "",
|
|
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()
|
|
|
|
binding.cancelButton.performClick()
|
|
|
|
verify { interactor.onCancelButtonClicked() }
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN an existing address WHEN editor is opened THEN the form fields are correctly mapped to the address fields`() {
|
|
val address = generateAddress()
|
|
|
|
val addressEditorView = spyk(
|
|
AddressEditorView(
|
|
binding = binding,
|
|
interactor = interactor,
|
|
address = address,
|
|
),
|
|
)
|
|
addressEditorView.bind()
|
|
|
|
assertEquals("PostalCode", binding.zipInput.text.toString())
|
|
assertEquals(address.addressLevel1, binding.subregionDropDown.selectedItem.toString())
|
|
assertEquals("City", binding.cityInput.text.toString())
|
|
assertEquals("Street", binding.streetAddressInput.text.toString())
|
|
assertEquals("Name", binding.nameInput.text.toString())
|
|
assertEquals("email@mozilla.com", binding.emailInput.text.toString())
|
|
assertEquals("Telephone", binding.phoneInput.text.toString())
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN an existing address WHEN editor is opened THEN the delete address button is visible`() = runBlocking {
|
|
val addressEditorView = spyk(
|
|
AddressEditorView(
|
|
binding = binding,
|
|
interactor = interactor,
|
|
address = address,
|
|
),
|
|
)
|
|
addressEditorView.bind()
|
|
|
|
assertEquals(View.VISIBLE, binding.deleteButton.visibility)
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN an existing address WHEN the delete address button is clicked THEN confirm delete dialog is shown`() = runBlocking {
|
|
val addressEditorView = spyk(
|
|
AddressEditorView(
|
|
binding = binding,
|
|
interactor = interactor,
|
|
address = address,
|
|
),
|
|
)
|
|
addressEditorView.bind()
|
|
|
|
binding.deleteButton.performClick()
|
|
|
|
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(
|
|
AddressEditorView(
|
|
binding = binding,
|
|
interactor = interactor,
|
|
address = generateAddress(country = "CA"),
|
|
),
|
|
)
|
|
addressEditorView.bind()
|
|
|
|
assertEquals(AddressUtils.countries["CA"]?.displayName, binding.countryDropDown.selectedItem.toString())
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN existing address and region not in supported countries WHEN country dropdown is bound THEN adapter sets dropdown to lower priority`() {
|
|
val addressEditorView = spyk(
|
|
AddressEditorView(
|
|
binding = binding,
|
|
interactor = interactor,
|
|
region = RegionState.Default,
|
|
address = generateAddress(country = "XX"),
|
|
),
|
|
)
|
|
addressEditorView.bind()
|
|
|
|
assertEquals(AddressUtils.countries[DEFAULT_COUNTRY]!!.displayName, binding.countryDropDown.selectedItem.toString())
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN search region and no address WHEN country dropdown is bound THEN adapter sets country dropdown to home region`() {
|
|
val addressEditorView = AddressEditorView(
|
|
binding = binding,
|
|
interactor = interactor,
|
|
region = RegionState("CA", "US"),
|
|
address = null,
|
|
)
|
|
addressEditorView.bind()
|
|
|
|
assertEquals(AddressUtils.countries["CA"]?.displayName, binding.countryDropDown.selectedItem.toString())
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN search region not in supported countries WHEN country dropdown is bound THEN adapter sets dropdown to lower priority`() {
|
|
val addressEditorView = AddressEditorView(
|
|
binding = binding,
|
|
interactor = interactor,
|
|
region = RegionState.Default,
|
|
address = null,
|
|
)
|
|
addressEditorView.bind()
|
|
|
|
assertEquals(AddressUtils.countries[DEFAULT_COUNTRY]!!.displayName, binding.countryDropDown.selectedItem.toString())
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN no address or search region WHEN country dropdown is bound THEN adapter sets dropdown to default`() {
|
|
val addressEditorView = AddressEditorView(
|
|
binding = binding,
|
|
interactor = interactor,
|
|
region = null,
|
|
address = null,
|
|
)
|
|
addressEditorView.bind()
|
|
|
|
assertEquals(AddressUtils.countries[DEFAULT_COUNTRY]!!.displayName, binding.countryDropDown.selectedItem.toString())
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN an existing address WHEN the save button is clicked THEN proper metrics are recorded`() = runBlocking {
|
|
assertNull(Addresses.updated.testGetValue())
|
|
|
|
val addressEditorView = spyk(AddressEditorView(binding, interactor, address = address))
|
|
addressEditorView.bind()
|
|
|
|
binding.saveButton.performClick()
|
|
|
|
assertNotNull(Addresses.updated.testGetValue())
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN a new address WHEN the save button is clicked THEN proper metrics are recorded`() = runBlocking {
|
|
assertNull(Addresses.saved.testGetValue())
|
|
|
|
val addressEditorView = spyk(AddressEditorView(binding, interactor))
|
|
addressEditorView.bind()
|
|
|
|
binding.saveButton.performClick()
|
|
|
|
assertNotNull(Addresses.saved.testGetValue())
|
|
}
|
|
|
|
private fun generateAddress(country: String = "US", addressLevel1: String = "Oregon") = Address(
|
|
guid = "123",
|
|
name = "Name",
|
|
organization = "Organization",
|
|
streetAddress = "Street",
|
|
addressLevel3 = "Suburb",
|
|
addressLevel2 = "City",
|
|
addressLevel1 = addressLevel1,
|
|
postalCode = "PostalCode",
|
|
country = country,
|
|
tel = "Telephone",
|
|
email = "email@mozilla.com",
|
|
timeCreated = 0L,
|
|
timeLastUsed = 1L,
|
|
timeLastModified = 1L,
|
|
timesUsed = 2L,
|
|
)
|
|
}
|