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.
205 lines
7.6 KiB
Kotlin
205 lines
7.6 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.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.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.ext.components
|
|
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`() {
|
|
val searchDialogFragment = spyk(fragment)
|
|
val interactor = spyk(SearchDialogInteractor(mockk()))
|
|
|
|
every { searchDialogFragment.interactor } returns interactor
|
|
|
|
val defaultSearchEngine: SearchEngine = mockk {
|
|
every { id } returns "default"
|
|
}
|
|
val otherSearchEngine: SearchEngine = mockk {
|
|
every { id } returns "other"
|
|
}
|
|
|
|
every { searchDialogFragment.requireContext() } returns testContext
|
|
every { testContext.components.core.store.state.search } returns SearchState(
|
|
regionSearchEngines = listOf(defaultSearchEngine, otherSearchEngine),
|
|
userSelectedSearchEngineId = "default",
|
|
)
|
|
|
|
searchDialogFragment.maybeSelectShortcutEngine(defaultSearchEngine.id)
|
|
|
|
verify { 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`() {
|
|
val searchDialogFragment = spyk(fragment)
|
|
val interactor = spyk(SearchDialogInteractor(mockk()))
|
|
|
|
every { searchDialogFragment.interactor } returns interactor
|
|
every { interactor.onSearchShortcutEngineSelected(any()) } just Runs
|
|
|
|
val defaultSearchEngine: SearchEngine = mockk {
|
|
every { id } returns "default"
|
|
}
|
|
val otherSearchEngine: SearchEngine = mockk {
|
|
every { id } returns "other"
|
|
}
|
|
|
|
every { searchDialogFragment.requireContext() } returns testContext
|
|
every { testContext.components.core.store.state.search } returns SearchState(
|
|
regionSearchEngines = listOf(defaultSearchEngine, otherSearchEngine),
|
|
userSelectedSearchEngineId = "default",
|
|
)
|
|
|
|
searchDialogFragment.maybeSelectShortcutEngine(otherSearchEngine.id)
|
|
|
|
verify { interactor.onSearchShortcutEngineSelected(any()) }
|
|
}
|
|
|
|
@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"
|
|
}
|
|
}
|
|
}
|