Richard Pospesel pushed to branch tor-browser-102.2.1-12.0-2 at The Tor Project / Applications / fenix

Commits:

3 changed files:

Changes:

  • app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
    ... ... @@ -17,6 +17,7 @@ import android.view.LayoutInflater
    17 17
     import android.view.View
    
    18 18
     import android.view.ViewGroup
    
    19 19
     import android.view.accessibility.AccessibilityManager
    
    20
    +import android.widget.Toast
    
    20 21
     import androidx.annotation.CallSuper
    
    21 22
     import androidx.annotation.VisibleForTesting
    
    22 23
     import androidx.appcompat.app.AlertDialog
    
    ... ... @@ -1381,12 +1382,8 @@ abstract class BaseBrowserFragment :
    1381 1382
             if (inFullScreen) {
    
    1382 1383
                 // Close find in page bar if opened
    
    1383 1384
                 findInPageIntegration.onBackPressed()
    
    1384
    -            FenixSnackbar.make(
    
    1385
    -                view = binding.dynamicSnackbarContainer,
    
    1386
    -                duration = Snackbar.LENGTH_SHORT,
    
    1387
    -                isDisplayedWithBrowserToolbar = false
    
    1388
    -            )
    
    1389
    -                .setText(getString(R.string.full_screen_notification))
    
    1385
    +            Toast
    
    1386
    +                .makeText(requireContext(), R.string.full_screen_notification, Toast.LENGTH_SHORT)
    
    1390 1387
                     .show()
    
    1391 1388
                 activity?.enterToImmersiveMode()
    
    1392 1389
                 browserToolbarView.collapse()
    

  • app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt
    ... ... @@ -78,6 +78,7 @@ import org.mozilla.fenix.databinding.SearchSuggestionsHintBinding
    78 78
     import org.mozilla.fenix.ext.components
    
    79 79
     import org.mozilla.fenix.ext.increaseTapArea
    
    80 80
     import org.mozilla.fenix.ext.requireComponents
    
    81
    +import org.mozilla.fenix.ext.secure
    
    81 82
     import org.mozilla.fenix.ext.settings
    
    82 83
     import org.mozilla.fenix.search.awesomebar.AwesomeBarView
    
    83 84
     import org.mozilla.fenix.search.awesomebar.toSearchProviderState
    
    ... ... @@ -151,6 +152,10 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
    151 152
                 override fun onBackPressed() {
    
    152 153
                     this@SearchDialogFragment.onBackPressed()
    
    153 154
                 }
    
    155
    +        }.apply {
    
    156
    +            if ((requireActivity() as HomeActivity).browsingModeManager.mode.isPrivate) {
    
    157
    +                this.secure(requireActivity())
    
    158
    +            }
    
    154 159
             }
    
    155 160
         }
    
    156 161
     
    

  • app/src/test/java/org/mozilla/fenix/search/SearchDialogFragmentTest.kt
    1
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    
    2
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4
    +
    
    5
    +package org.mozilla.fenix.search
    
    6
    +
    
    7
    +import android.view.WindowManager.LayoutParams
    
    8
    +import androidx.fragment.app.Fragment
    
    9
    +import androidx.navigation.NavBackStackEntry
    
    10
    +import androidx.navigation.NavController
    
    11
    +import androidx.navigation.fragment.findNavController
    
    12
    +import io.mockk.Called
    
    13
    +import io.mockk.Runs
    
    14
    +import io.mockk.every
    
    15
    +import io.mockk.just
    
    16
    +import io.mockk.mockk
    
    17
    +import io.mockk.mockkStatic
    
    18
    +import io.mockk.spyk
    
    19
    +import io.mockk.unmockkStatic
    
    20
    +import io.mockk.verify
    
    21
    +import mozilla.components.browser.state.search.SearchEngine
    
    22
    +import mozilla.components.browser.state.state.SearchState
    
    23
    +import mozilla.components.browser.state.state.searchEngines
    
    24
    +import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine
    
    25
    +import mozilla.components.support.test.robolectric.testContext
    
    26
    +import org.junit.After
    
    27
    +import org.junit.Assert.assertEquals
    
    28
    +import org.junit.Assert.assertNull
    
    29
    +import org.junit.Assert.assertSame
    
    30
    +import org.junit.Before
    
    31
    +import org.junit.Test
    
    32
    +import org.junit.runner.RunWith
    
    33
    +import org.mozilla.fenix.HomeActivity
    
    34
    +import org.mozilla.fenix.components.Components
    
    35
    +import org.mozilla.fenix.ext.requireComponents
    
    36
    +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
    
    37
    +
    
    38
    +@RunWith(FenixRobolectricTestRunner::class)
    
    39
    +internal class SearchDialogFragmentTest {
    
    40
    +    private val navController: NavController = mockk()
    
    41
    +    private val fragment = SearchDialogFragment()
    
    42
    +
    
    43
    +    @Before
    
    44
    +    fun setup() {
    
    45
    +        mockkStatic("androidx.navigation.fragment.FragmentKt")
    
    46
    +        every { any<Fragment>().findNavController() } returns navController
    
    47
    +    }
    
    48
    +
    
    49
    +    @After
    
    50
    +    fun teardown() {
    
    51
    +        unmockkStatic("androidx.navigation.fragment.FragmentKt")
    
    52
    +    }
    
    53
    +
    
    54
    +    @Test
    
    55
    +    fun `GIVEN this is the only visible fragment WHEN asking for the previous destination THEN return null`() {
    
    56
    +        every { navController.backQueue } returns ArrayDeque(listOf(getDestination(fragmentName)))
    
    57
    +
    
    58
    +        assertNull(fragment.getPreviousDestination())
    
    59
    +    }
    
    60
    +
    
    61
    +    @Test
    
    62
    +    fun `GIVEN this and FragmentB on top of this are visible WHEN asking for the previous destination THEN return null`() {
    
    63
    +        every { navController.backQueue } returns ArrayDeque(
    
    64
    +            listOf(
    
    65
    +                getDestination(fragmentName),
    
    66
    +                getDestination("FragmentB"),
    
    67
    +            ),
    
    68
    +        )
    
    69
    +
    
    70
    +        assertNull(fragment.getPreviousDestination())
    
    71
    +    }
    
    72
    +
    
    73
    +    @Test
    
    74
    +    fun `GIVEN FragmentA, this and FragmentB are visible WHEN asking for the previous destination THEN return FragmentA`() {
    
    75
    +        val fragmentADestination = getDestination("FragmentA")
    
    76
    +        every { navController.backQueue } returns ArrayDeque(
    
    77
    +            listOf(
    
    78
    +                fragmentADestination,
    
    79
    +                getDestination(fragmentName),
    
    80
    +                getDestination("FragmentB"),
    
    81
    +            ),
    
    82
    +        )
    
    83
    +
    
    84
    +        assertSame(fragmentADestination, fragment.getPreviousDestination())
    
    85
    +    }
    
    86
    +
    
    87
    +    @Test
    
    88
    +    fun `GIVEN FragmentA and this on top of it are visible WHEN asking for the previous destination THEN return FragmentA`() {
    
    89
    +        val fragmentADestination = getDestination("FragmentA")
    
    90
    +        every { navController.backQueue } returns ArrayDeque(
    
    91
    +            listOf(
    
    92
    +                fragmentADestination,
    
    93
    +                getDestination(fragmentName),
    
    94
    +            ),
    
    95
    +        )
    
    96
    +
    
    97
    +        assertSame(fragmentADestination, fragment.getPreviousDestination())
    
    98
    +    }
    
    99
    +
    
    100
    +    @Test
    
    101
    +    fun `GIVEN the default search engine is currently selected WHEN checking the need to update the current search engine THEN don't to anything`() {
    
    102
    +        fragment.interactor = mockk()
    
    103
    +        val defaultSearchEngine: SearchEngine = mockk {
    
    104
    +            every { id } returns "default"
    
    105
    +        }
    
    106
    +        val otherSearchEngine: SearchEngine = mockk {
    
    107
    +            every { id } returns "other"
    
    108
    +        }
    
    109
    +        val components: Components = mockk {
    
    110
    +            every { core.store.state.search } returns mockk(relaxed = true) {
    
    111
    +                every { searchEngines } returns listOf(otherSearchEngine, defaultSearchEngine)
    
    112
    +            }
    
    113
    +        }
    
    114
    +        mockkStatic(
    
    115
    +            "org.mozilla.fenix.ext.FragmentKt",
    
    116
    +            "mozilla.components.browser.state.state.SearchStateKt",
    
    117
    +        ) {
    
    118
    +            every { any<Fragment>().requireComponents } returns components
    
    119
    +            every { any<SearchState>().selectedOrDefaultSearchEngine } returns defaultSearchEngine
    
    120
    +
    
    121
    +            fragment.maybeSelectShortcutEngine(defaultSearchEngine.id)
    
    122
    +
    
    123
    +            verify { fragment.interactor wasNot Called }
    
    124
    +        }
    
    125
    +    }
    
    126
    +
    
    127
    +    @Test
    
    128
    +    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`() {
    
    129
    +        fragment.interactor = mockk {
    
    130
    +            every { onSearchShortcutEngineSelected(any()) } just Runs
    
    131
    +        }
    
    132
    +        val defaultSearchEngine: SearchEngine = mockk {
    
    133
    +            every { id } returns "default"
    
    134
    +        }
    
    135
    +        val otherSearchEngine: SearchEngine = mockk {
    
    136
    +            every { id } returns "other"
    
    137
    +        }
    
    138
    +        val components: Components = mockk {
    
    139
    +            every { core.store.state.search } returns mockk(relaxed = true) {
    
    140
    +                every { searchEngines } returns listOf(otherSearchEngine, defaultSearchEngine)
    
    141
    +            }
    
    142
    +        }
    
    143
    +        mockkStatic(
    
    144
    +            "org.mozilla.fenix.ext.FragmentKt",
    
    145
    +            "mozilla.components.browser.state.state.SearchStateKt",
    
    146
    +        ) {
    
    147
    +            every { any<Fragment>().requireComponents } returns components
    
    148
    +            every { any<SearchState>().selectedOrDefaultSearchEngine } returns defaultSearchEngine
    
    149
    +
    
    150
    +            fragment.maybeSelectShortcutEngine(otherSearchEngine.id)
    
    151
    +
    
    152
    +            verify { fragment.interactor.onSearchShortcutEngineSelected(otherSearchEngine) }
    
    153
    +        }
    
    154
    +    }
    
    155
    +
    
    156
    +    @Test
    
    157
    +    fun `GIVEN the currently selected search engine is unknown WHEN checking the need to update the current search engine THEN don't do anything`() {
    
    158
    +        fragment.interactor = mockk()
    
    159
    +
    
    160
    +        fragment.maybeSelectShortcutEngine(null)
    
    161
    +
    
    162
    +        verify { fragment.interactor wasNot Called }
    
    163
    +    }
    
    164
    +
    
    165
    +    @Test
    
    166
    +    fun `GIVEN app is in private mode WHEN search dialog is created THEN the dialog is secure`() {
    
    167
    +        val activity: HomeActivity = mockk(relaxed = true)
    
    168
    +        val fragment = spyk(SearchDialogFragment())
    
    169
    +        val layoutParams = LayoutParams()
    
    170
    +        layoutParams.flags = LayoutParams.FLAG_SECURE
    
    171
    +
    
    172
    +        every { activity.browsingModeManager.mode.isPrivate } returns true
    
    173
    +        every { activity.window } returns mockk(relaxed = true) {
    
    174
    +            every { attributes } returns LayoutParams().apply { flags = LayoutParams.FLAG_SECURE }
    
    175
    +        }
    
    176
    +        every { fragment.requireActivity() } returns activity
    
    177
    +        every { fragment.requireContext() } returns testContext
    
    178
    +
    
    179
    +        val dialog = fragment.onCreateDialog(null)
    
    180
    +
    
    181
    +        assertEquals(LayoutParams.FLAG_SECURE, dialog.window?.attributes?.flags!! and LayoutParams.FLAG_SECURE)
    
    182
    +    }
    
    183
    +
    
    184
    +    @Test
    
    185
    +    fun `GIVEN app is in normal mode WHEN search dialog is created THEN the dialog is not secure`() {
    
    186
    +        val activity: HomeActivity = mockk(relaxed = true)
    
    187
    +        val fragment = spyk(SearchDialogFragment())
    
    188
    +        val layoutParams = LayoutParams()
    
    189
    +        layoutParams.flags = LayoutParams.FLAG_SECURE
    
    190
    +
    
    191
    +        every { activity.browsingModeManager.mode.isPrivate } returns false
    
    192
    +        every { activity.window } returns mockk(relaxed = true) {
    
    193
    +            every { attributes } returns LayoutParams().apply { flags = LayoutParams.FLAG_SECURE }
    
    194
    +        }
    
    195
    +        every { fragment.requireActivity() } returns activity
    
    196
    +        every { fragment.requireContext() } returns testContext
    
    197
    +
    
    198
    +        val dialog = fragment.onCreateDialog(null)
    
    199
    +
    
    200
    +        assertEquals(0, dialog.window?.attributes?.flags!! and LayoutParams.FLAG_SECURE)
    
    201
    +    }
    
    202
    +}
    
    203
    +
    
    204
    +private val fragmentName = SearchDialogFragment::class.java.canonicalName?.substringAfterLast('.')!!
    
    205
    +
    
    206
    +private fun getDestination(destinationName: String): NavBackStackEntry {
    
    207
    +    return mockk {
    
    208
    +        every { destination } returns mockk {
    
    209
    +            every { displayName } returns "test.id/$destinationName"
    
    210
    +        }
    
    211
    +    }
    
    212
    +}