diff --git a/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/PromptFeatureTest.kt b/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/PromptFeatureTest.kt index c2c7d856384..26ae85281c6 100644 --- a/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/PromptFeatureTest.kt +++ b/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/PromptFeatureTest.kt @@ -38,9 +38,11 @@ import mozilla.components.concept.engine.prompt.PromptRequest.MultipleChoice import mozilla.components.concept.engine.prompt.PromptRequest.SingleChoice import mozilla.components.concept.engine.prompt.PromptRequest.TextPrompt import mozilla.components.concept.engine.prompt.ShareData +import mozilla.components.concept.storage.Address import mozilla.components.concept.storage.CreditCardEntry import mozilla.components.concept.storage.Login import mozilla.components.concept.storage.LoginEntry +import mozilla.components.feature.prompts.address.AddressPicker import mozilla.components.feature.prompts.concept.SelectablePromptView import mozilla.components.feature.prompts.creditcard.CreditCardPicker import mozilla.components.feature.prompts.creditcard.CreditCardSaveDialogFragment @@ -89,6 +91,7 @@ class PromptFeatureTest { private lateinit var fragmentManager: FragmentManager private lateinit var loginPicker: LoginPicker private lateinit var creditCardPicker: CreditCardPicker + private lateinit var addressPicker: AddressPicker private val tabId = "test-tab" private fun tab(): TabSessionState? { @@ -111,6 +114,7 @@ class PromptFeatureTest { ) loginPicker = mock() creditCardPicker = mock() + addressPicker = mock() fragmentManager = mockFragmentManager() } @@ -592,6 +596,57 @@ class PromptFeatureTest { verify(feature.creditCardPicker!!).dismissSelectCreditCardRequest(selectCreditCardRequest) } + @Test + fun `WHEN dismissSelectPrompts is called THEN the active addressPicker dismiss should be called`() { + val addressPickerView: SelectablePromptView
= mock() + val feature = spy( + PromptFeature( + mock(), + store, + fragmentManager = fragmentManager, + addressPickerView = addressPickerView + ) { } + ) + feature.addressPicker = addressPicker + feature.activePromptRequest = mock() + + whenever(addressPickerView.asView()).thenReturn(mock()) + whenever(addressPickerView.asView().visibility).thenReturn(View.VISIBLE) + + feature.dismissSelectPrompts() + verify(feature.addressPicker!!, never()).dismissSelectAddressRequest(any()) + + val selectAddressPromptRequest = mock() + feature.activePromptRequest = selectAddressPromptRequest + + feature.dismissSelectPrompts() + + verify(feature.addressPicker!!).dismissSelectAddressRequest(selectAddressPromptRequest) + } + + @Test + fun `GIVEN addressPickerView is not visible WHEN dismissSelectPrompts is called THEN dismissSelectPrompts returns false`() { + val addressPickerView: SelectablePromptView
= mock() + val feature = spy( + PromptFeature( + mock(), + store, + fragmentManager = fragmentManager, + addressPickerView = addressPickerView + ) { } + ) + val selectAddressRequest = mock() + feature.addressPicker = addressPicker + feature.activePromptRequest = selectAddressRequest + + whenever(addressPickerView.asView()).thenReturn(mock()) + whenever(addressPickerView.asView().visibility).thenReturn(View.GONE) + + val result = feature.dismissSelectPrompts() + + assertEquals(false, result) + } + @Test fun `Calling onCancel will consume promptRequest`() { val feature = diff --git a/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressAdapterTest.kt b/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressAdapterTest.kt new file mode 100644 index 00000000000..d6d5ca2200b --- /dev/null +++ b/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressAdapterTest.kt @@ -0,0 +1,79 @@ + +package mozilla.components.feature.prompts.address + +import android.view.LayoutInflater +import android.widget.TextView +import androidx.test.ext.junit.runners.AndroidJUnit4 +import mozilla.components.concept.storage.Address +import mozilla.components.feature.prompts.R +import mozilla.components.support.test.robolectric.testContext +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class AddressAdapterTest { + + private val address = Address( + guid = "1", + givenName = "Location", + additionalName = "Location", + familyName = "Location", + organization = "Mozilla", + streetAddress = "1230 Main st", + addressLevel3 = "Location3", + addressLevel2 = "Location2", + addressLevel1 = "Location1", + postalCode = "90237", + country = "USA", + tel = "00", + email = "email" + ) + + @Test + fun testAddressDiffCallback() { + val address2 = address.copy() + + assertTrue( + AddressDiffCallback.areItemsTheSame(address, address2) + ) + assertTrue( + AddressDiffCallback.areContentsTheSame(address, address2) + ) + + val address3 = address.copy(guid = "2") + + assertFalse( + AddressDiffCallback.areItemsTheSame(address, address3) + ) + assertFalse( + AddressDiffCallback.areItemsTheSame(address, address3) + ) + } + + @Test + fun `WHEN an address is bound to the adapter THEN set the address display name`() { + val view = + LayoutInflater.from(testContext).inflate(R.layout.mozac_feature_prompts_address_list_item, null) + val addressName: TextView = view.findViewById(R.id.address_name) + + AddressViewHolder(view) {}.bind(address) + + assertEquals(address.displayFormat(), addressName.text) + } + + @Test + fun `WHEN an address item is clicked THEN call the onAddressSelected callback`() { + var addressSelected = false + val view = + LayoutInflater.from(testContext).inflate(R.layout.mozac_feature_prompts_address_list_item, null) + val onAddressSelect: (Address) -> Unit = { addressSelected = true } + + AddressViewHolder(view, onAddressSelect).bind(address) + view.performClick() + + assertTrue(addressSelected) + } +} diff --git a/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressPickerTest.kt b/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressPickerTest.kt new file mode 100644 index 00000000000..daa5c030dab --- /dev/null +++ b/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressPickerTest.kt @@ -0,0 +1,107 @@ +/* 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 mozilla.components.feature.prompts.address + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.ContentState +import mozilla.components.browser.state.state.CustomTabSessionState +import mozilla.components.browser.state.state.TabSessionState +import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.concept.engine.prompt.PromptRequest +import mozilla.components.concept.storage.Address +import mozilla.components.support.test.mock +import mozilla.components.support.test.whenever +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.verify + +@RunWith(AndroidJUnit4::class) +class AddressPickerTest { + + private lateinit var store: BrowserStore + private lateinit var state: BrowserState + private lateinit var addressPicker: AddressPicker + private lateinit var addressSelectBar: AddressSelectBar + + private val address = Address( + guid = "1", + givenName = "Location", + additionalName = "Location", + familyName = "Location", + organization = "Mozilla", + streetAddress = "1230 Main st", + addressLevel3 = "Location3", + addressLevel2 = "Location2", + addressLevel1 = "Location1", + postalCode = "90237", + country = "USA", + tel = "00", + email = "email" + ) + var onDismissCalled = false + var confirmedAddress: Address? = null + private val promptRequest = PromptRequest.SelectAddress( + addresses = listOf(address), + onDismiss = { onDismissCalled = true }, + onConfirm = { confirmedAddress = it } + ) + + var selectAddressCalled = false + private val selectAddressCallback: () -> Unit = { selectAddressCalled = true } + + @Before + fun setup() { + store = mock() + state = mock() + addressSelectBar = mock() + addressPicker = AddressPicker( + store = store, + addressSelectBar = addressSelectBar, + selectAddressCallback = selectAddressCallback, + ) + + whenever(store.state).thenReturn(state) + } + + @Test + fun `WHEN onOptionSelect is called with an address THEN selectAddressCallback is invoked and prompt is hidden`() { + assertNull(addressPicker.selectedAddress) + val content: ContentState = mock() + whenever(content.promptRequests).thenReturn(listOf(promptRequest)) + val selectedTab = TabSessionState("browser-tab", content, mock(), mock()) + whenever(state.selectedTabId).thenReturn(selectedTab.id) + whenever(state.tabs).thenReturn(listOf(selectedTab)) + + addressPicker.onOptionSelect(address) + + verify(addressSelectBar).hidePrompt() + assertTrue(selectAddressCalled) + assertEquals(address, addressPicker.selectedAddress) + } + + @Test + fun `GIVEN a prompt request WHEN handleSelectAddressRequest is called THEN the prompt is shown with the provided addresses`() { + addressPicker.handleSelectAddressRequest(promptRequest) + + verify(addressSelectBar).showPrompt(promptRequest.addresses) + } + + @Test + fun `GIVEN a custom tab and a prompt request WHEN handleSelectAddressRequest is called THEN the prompt is shown with the provided addresses`() { + val customTabContent: ContentState = mock() + val customTab = CustomTabSessionState("custom-tab", customTabContent, mock(), mock()) + whenever(customTabContent.promptRequests).thenReturn(listOf(promptRequest)) + whenever(state.customTabs).thenReturn(listOf(customTab)) + + addressPicker.handleSelectAddressRequest(promptRequest) + + verify(addressSelectBar).showPrompt(promptRequest.addresses) + } +} diff --git a/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressSelectBarTest.kt b/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressSelectBarTest.kt new file mode 100644 index 00000000000..1d7751e2e78 --- /dev/null +++ b/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressSelectBarTest.kt @@ -0,0 +1,99 @@ +/* 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 mozilla.components.feature.prompts.address + +import android.widget.LinearLayout +import androidx.appcompat.widget.AppCompatTextView +import androidx.core.view.isVisible +import androidx.recyclerview.widget.RecyclerView +import androidx.test.ext.junit.runners.AndroidJUnit4 +import mozilla.components.concept.storage.Address +import mozilla.components.feature.prompts.R +import mozilla.components.feature.prompts.concept.SelectablePromptView +import mozilla.components.support.test.ext.appCompatContext +import mozilla.components.support.test.mock +import mozilla.components.support.test.robolectric.testContext +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.verify + +@RunWith(AndroidJUnit4::class) +class AddressSelectBarTest { + + private lateinit var addressSelectBar: AddressSelectBar + + private val address = Address( + guid = "1", + givenName = "Location", + additionalName = "Location", + familyName = "Location", + organization = "Mozilla", + streetAddress = "1230 Main st", + addressLevel3 = "Location3", + addressLevel2 = "Location2", + addressLevel1 = "Location1", + postalCode = "90237", + country = "USA", + tel = "00", + email = "email" + ) + + @Before + fun setup() { + addressSelectBar = AddressSelectBar(appCompatContext) + } + + @Test + fun `WHEN showPrompt is called THEN the select bar is shown`() { + val addresses = listOf(address) + + addressSelectBar.showPrompt(addresses) + + assertTrue(addressSelectBar.isVisible) + } + + @Test + fun `WHEN hidePrompt is called THEN the select bar is hidden`() { + assertTrue(addressSelectBar.isVisible) + + addressSelectBar.hidePrompt() + + assertFalse(addressSelectBar.isVisible) + } + + @Test + fun `WHEN the selectBar header is clicked two times THEN the list of addresses is shown, then hidden`() { + addressSelectBar.showPrompt(listOf(address)) + addressSelectBar.findViewById(R.id.select_address_header).performClick() + + assertTrue(addressSelectBar.findViewById(R.id.address_list).isVisible) + + addressSelectBar.findViewById(R.id.select_address_header).performClick() + + assertFalse(addressSelectBar.findViewById(R.id.address_list).isVisible) + } + + @Test + fun `GIVEN a listener WHEN an address is clicked THEN onOptionSelected is called`() { + val listener: SelectablePromptView.Listener
= mock() + + assertNull(addressSelectBar.listener) + + addressSelectBar.listener = listener + + addressSelectBar.showPrompt(listOf(address)) + val adapter = addressSelectBar.findViewById(R.id.address_list).adapter as AddressAdapter + val holder = adapter.onCreateViewHolder(LinearLayout(testContext), 0) + adapter.bindViewHolder(holder, 0) + + holder.itemView.performClick() + + verify(listener).onOptionSelect(address) + } +}