Loading app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt +5 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ import org.mozilla.fenix.databinding.SearchSuggestionsHintBinding import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.increaseTapArea import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.secure import org.mozilla.fenix.ext.settings import org.mozilla.fenix.search.awesomebar.AwesomeBarView import org.mozilla.fenix.search.awesomebar.toSearchProviderState Loading Loading @@ -151,6 +152,10 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { override fun onBackPressed() { this@SearchDialogFragment.onBackPressed() } }.apply { if ((requireActivity() as HomeActivity).browsingModeManager.mode.isPrivate) { this.secure(requireActivity()) } } } Loading app/src/test/java/org/mozilla/fenix/search/SearchDialogFragmentTest.kt 0 → 100644 +212 −0 Original line number Diff line number Diff line /* 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.search import android.view.WindowManager.LayoutParams import androidx.fragment.app.Fragment import androidx.navigation.NavBackStackEntry import androidx.navigation.NavController import androidx.navigation.fragment.findNavController import io.mockk.Called import io.mockk.Runs import io.mockk.every import io.mockk.just import io.mockk.mockk import io.mockk.mockkStatic import io.mockk.spyk import io.mockk.unmockkStatic import io.mockk.verify import mozilla.components.browser.state.search.SearchEngine import mozilla.components.browser.state.state.SearchState import mozilla.components.browser.state.state.searchEngines import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine import mozilla.components.support.test.robolectric.testContext import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Assert.assertSame import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.components.Components import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.helpers.FenixRobolectricTestRunner @RunWith(FenixRobolectricTestRunner::class) internal class SearchDialogFragmentTest { private val navController: NavController = mockk() private val fragment = SearchDialogFragment() @Before fun setup() { mockkStatic("androidx.navigation.fragment.FragmentKt") every { any<Fragment>().findNavController() } returns navController } @After fun teardown() { unmockkStatic("androidx.navigation.fragment.FragmentKt") } @Test fun `GIVEN this is the only visible fragment WHEN asking for the previous destination THEN return null`() { every { navController.backQueue } returns ArrayDeque(listOf(getDestination(fragmentName))) assertNull(fragment.getPreviousDestination()) } @Test fun `GIVEN this and FragmentB on top of this are visible WHEN asking for the previous destination THEN return null`() { every { navController.backQueue } returns ArrayDeque( listOf( getDestination(fragmentName), getDestination("FragmentB"), ), ) assertNull(fragment.getPreviousDestination()) } @Test fun `GIVEN FragmentA, this and FragmentB are visible WHEN asking for the previous destination THEN return FragmentA`() { val fragmentADestination = getDestination("FragmentA") every { navController.backQueue } returns ArrayDeque( listOf( fragmentADestination, getDestination(fragmentName), getDestination("FragmentB"), ), ) assertSame(fragmentADestination, fragment.getPreviousDestination()) } @Test fun `GIVEN FragmentA and this on top of it are visible WHEN asking for the previous destination THEN return FragmentA`() { val fragmentADestination = getDestination("FragmentA") every { navController.backQueue } returns ArrayDeque( listOf( fragmentADestination, getDestination(fragmentName), ), ) assertSame(fragmentADestination, fragment.getPreviousDestination()) } @Test fun `GIVEN the default search engine is currently selected WHEN checking the need to update the current search engine THEN don't to anything`() { fragment.interactor = mockk() val defaultSearchEngine: SearchEngine = mockk { every { id } returns "default" } val otherSearchEngine: SearchEngine = mockk { every { id } returns "other" } val components: Components = mockk { every { core.store.state.search } returns mockk(relaxed = true) { every { searchEngines } returns listOf(otherSearchEngine, defaultSearchEngine) } } mockkStatic( "org.mozilla.fenix.ext.FragmentKt", "mozilla.components.browser.state.state.SearchStateKt", ) { every { any<Fragment>().requireComponents } returns components every { any<SearchState>().selectedOrDefaultSearchEngine } returns defaultSearchEngine fragment.maybeSelectShortcutEngine(defaultSearchEngine.id) verify { fragment.interactor wasNot Called } } } @Test fun `GIVEN the default search engine is not currently selected WHEN checking the need to update the current search engine THEN update it to the current engine`() { fragment.interactor = mockk { every { onSearchShortcutEngineSelected(any()) } just Runs } val defaultSearchEngine: SearchEngine = mockk { every { id } returns "default" } val otherSearchEngine: SearchEngine = mockk { every { id } returns "other" } val components: Components = mockk { every { core.store.state.search } returns mockk(relaxed = true) { every { searchEngines } returns listOf(otherSearchEngine, defaultSearchEngine) } } mockkStatic( "org.mozilla.fenix.ext.FragmentKt", "mozilla.components.browser.state.state.SearchStateKt", ) { every { any<Fragment>().requireComponents } returns components every { any<SearchState>().selectedOrDefaultSearchEngine } returns defaultSearchEngine fragment.maybeSelectShortcutEngine(otherSearchEngine.id) verify { fragment.interactor.onSearchShortcutEngineSelected(otherSearchEngine) } } } @Test fun `GIVEN the currently selected search engine is unknown WHEN checking the need to update the current search engine THEN don't do anything`() { fragment.interactor = mockk() fragment.maybeSelectShortcutEngine(null) verify { fragment.interactor wasNot Called } } @Test fun `GIVEN app is in private mode WHEN search dialog is created THEN the dialog is secure`() { val activity: HomeActivity = mockk(relaxed = true) val fragment = spyk(SearchDialogFragment()) val layoutParams = LayoutParams() layoutParams.flags = LayoutParams.FLAG_SECURE every { activity.browsingModeManager.mode.isPrivate } returns true every { activity.window } returns mockk(relaxed = true) { every { attributes } returns LayoutParams().apply { flags = LayoutParams.FLAG_SECURE } } every { fragment.requireActivity() } returns activity every { fragment.requireContext() } returns testContext val dialog = fragment.onCreateDialog(null) assertEquals(LayoutParams.FLAG_SECURE, dialog.window?.attributes?.flags!! and LayoutParams.FLAG_SECURE) } @Test fun `GIVEN app is in normal mode WHEN search dialog is created THEN the dialog is not secure`() { val activity: HomeActivity = mockk(relaxed = true) val fragment = spyk(SearchDialogFragment()) val layoutParams = LayoutParams() layoutParams.flags = LayoutParams.FLAG_SECURE every { activity.browsingModeManager.mode.isPrivate } returns false every { activity.window } returns mockk(relaxed = true) { every { attributes } returns LayoutParams().apply { flags = LayoutParams.FLAG_SECURE } } every { fragment.requireActivity() } returns activity every { fragment.requireContext() } returns testContext val dialog = fragment.onCreateDialog(null) assertEquals(0, dialog.window?.attributes?.flags!! and LayoutParams.FLAG_SECURE) } } private val fragmentName = SearchDialogFragment::class.java.canonicalName?.substringAfterLast('.')!! private fun getDestination(destinationName: String): NavBackStackEntry { return mockk { every { destination } returns mockk { every { displayName } returns "test.id/$destinationName" } } } Loading
app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt +5 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ import org.mozilla.fenix.databinding.SearchSuggestionsHintBinding import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.increaseTapArea import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.secure import org.mozilla.fenix.ext.settings import org.mozilla.fenix.search.awesomebar.AwesomeBarView import org.mozilla.fenix.search.awesomebar.toSearchProviderState Loading Loading @@ -151,6 +152,10 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { override fun onBackPressed() { this@SearchDialogFragment.onBackPressed() } }.apply { if ((requireActivity() as HomeActivity).browsingModeManager.mode.isPrivate) { this.secure(requireActivity()) } } } Loading
app/src/test/java/org/mozilla/fenix/search/SearchDialogFragmentTest.kt 0 → 100644 +212 −0 Original line number Diff line number Diff line /* 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.search import android.view.WindowManager.LayoutParams import androidx.fragment.app.Fragment import androidx.navigation.NavBackStackEntry import androidx.navigation.NavController import androidx.navigation.fragment.findNavController import io.mockk.Called import io.mockk.Runs import io.mockk.every import io.mockk.just import io.mockk.mockk import io.mockk.mockkStatic import io.mockk.spyk import io.mockk.unmockkStatic import io.mockk.verify import mozilla.components.browser.state.search.SearchEngine import mozilla.components.browser.state.state.SearchState import mozilla.components.browser.state.state.searchEngines import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine import mozilla.components.support.test.robolectric.testContext import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Assert.assertSame import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.components.Components import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.helpers.FenixRobolectricTestRunner @RunWith(FenixRobolectricTestRunner::class) internal class SearchDialogFragmentTest { private val navController: NavController = mockk() private val fragment = SearchDialogFragment() @Before fun setup() { mockkStatic("androidx.navigation.fragment.FragmentKt") every { any<Fragment>().findNavController() } returns navController } @After fun teardown() { unmockkStatic("androidx.navigation.fragment.FragmentKt") } @Test fun `GIVEN this is the only visible fragment WHEN asking for the previous destination THEN return null`() { every { navController.backQueue } returns ArrayDeque(listOf(getDestination(fragmentName))) assertNull(fragment.getPreviousDestination()) } @Test fun `GIVEN this and FragmentB on top of this are visible WHEN asking for the previous destination THEN return null`() { every { navController.backQueue } returns ArrayDeque( listOf( getDestination(fragmentName), getDestination("FragmentB"), ), ) assertNull(fragment.getPreviousDestination()) } @Test fun `GIVEN FragmentA, this and FragmentB are visible WHEN asking for the previous destination THEN return FragmentA`() { val fragmentADestination = getDestination("FragmentA") every { navController.backQueue } returns ArrayDeque( listOf( fragmentADestination, getDestination(fragmentName), getDestination("FragmentB"), ), ) assertSame(fragmentADestination, fragment.getPreviousDestination()) } @Test fun `GIVEN FragmentA and this on top of it are visible WHEN asking for the previous destination THEN return FragmentA`() { val fragmentADestination = getDestination("FragmentA") every { navController.backQueue } returns ArrayDeque( listOf( fragmentADestination, getDestination(fragmentName), ), ) assertSame(fragmentADestination, fragment.getPreviousDestination()) } @Test fun `GIVEN the default search engine is currently selected WHEN checking the need to update the current search engine THEN don't to anything`() { fragment.interactor = mockk() val defaultSearchEngine: SearchEngine = mockk { every { id } returns "default" } val otherSearchEngine: SearchEngine = mockk { every { id } returns "other" } val components: Components = mockk { every { core.store.state.search } returns mockk(relaxed = true) { every { searchEngines } returns listOf(otherSearchEngine, defaultSearchEngine) } } mockkStatic( "org.mozilla.fenix.ext.FragmentKt", "mozilla.components.browser.state.state.SearchStateKt", ) { every { any<Fragment>().requireComponents } returns components every { any<SearchState>().selectedOrDefaultSearchEngine } returns defaultSearchEngine fragment.maybeSelectShortcutEngine(defaultSearchEngine.id) verify { fragment.interactor wasNot Called } } } @Test fun `GIVEN the default search engine is not currently selected WHEN checking the need to update the current search engine THEN update it to the current engine`() { fragment.interactor = mockk { every { onSearchShortcutEngineSelected(any()) } just Runs } val defaultSearchEngine: SearchEngine = mockk { every { id } returns "default" } val otherSearchEngine: SearchEngine = mockk { every { id } returns "other" } val components: Components = mockk { every { core.store.state.search } returns mockk(relaxed = true) { every { searchEngines } returns listOf(otherSearchEngine, defaultSearchEngine) } } mockkStatic( "org.mozilla.fenix.ext.FragmentKt", "mozilla.components.browser.state.state.SearchStateKt", ) { every { any<Fragment>().requireComponents } returns components every { any<SearchState>().selectedOrDefaultSearchEngine } returns defaultSearchEngine fragment.maybeSelectShortcutEngine(otherSearchEngine.id) verify { fragment.interactor.onSearchShortcutEngineSelected(otherSearchEngine) } } } @Test fun `GIVEN the currently selected search engine is unknown WHEN checking the need to update the current search engine THEN don't do anything`() { fragment.interactor = mockk() fragment.maybeSelectShortcutEngine(null) verify { fragment.interactor wasNot Called } } @Test fun `GIVEN app is in private mode WHEN search dialog is created THEN the dialog is secure`() { val activity: HomeActivity = mockk(relaxed = true) val fragment = spyk(SearchDialogFragment()) val layoutParams = LayoutParams() layoutParams.flags = LayoutParams.FLAG_SECURE every { activity.browsingModeManager.mode.isPrivate } returns true every { activity.window } returns mockk(relaxed = true) { every { attributes } returns LayoutParams().apply { flags = LayoutParams.FLAG_SECURE } } every { fragment.requireActivity() } returns activity every { fragment.requireContext() } returns testContext val dialog = fragment.onCreateDialog(null) assertEquals(LayoutParams.FLAG_SECURE, dialog.window?.attributes?.flags!! and LayoutParams.FLAG_SECURE) } @Test fun `GIVEN app is in normal mode WHEN search dialog is created THEN the dialog is not secure`() { val activity: HomeActivity = mockk(relaxed = true) val fragment = spyk(SearchDialogFragment()) val layoutParams = LayoutParams() layoutParams.flags = LayoutParams.FLAG_SECURE every { activity.browsingModeManager.mode.isPrivate } returns false every { activity.window } returns mockk(relaxed = true) { every { attributes } returns LayoutParams().apply { flags = LayoutParams.FLAG_SECURE } } every { fragment.requireActivity() } returns activity every { fragment.requireContext() } returns testContext val dialog = fragment.onCreateDialog(null) assertEquals(0, dialog.window?.attributes?.flags!! and LayoutParams.FLAG_SECURE) } } private val fragmentName = SearchDialogFragment::class.java.canonicalName?.substringAfterLast('.')!! private fun getDestination(destinationName: String): NavBackStackEntry { return mockk { every { destination } returns mockk { every { displayName } returns "test.id/$destinationName" } } }