diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 692947a22..cc0f4dbd4 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -50,7 +50,6 @@ import org.jetbrains.anko.constraint.layout.ConstraintSetBuilder.Side.START import org.jetbrains.anko.constraint.layout.ConstraintSetBuilder.Side.TOP import org.jetbrains.anko.constraint.layout.applyConstraintSet import org.mozilla.fenix.BrowserDirection -import org.mozilla.fenix.BrowsingMode import org.mozilla.fenix.FenixViewModelProvider import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R @@ -234,22 +233,17 @@ class HomeFragment : Fragment(), AccountObserver { requireComponents.analytics.metrics.track(Event.SearchBarTapped(Event.SearchBarTapped.Source.HOME)) } - val isPrivate = browsingModeManager.mode.isPrivate - - privateBrowsingButton.contentDescription = - contentDescriptionForPrivateBrowsingButton(isPrivate) - - privateBrowsingButton.setOnClickListener { + PrivateBrowsingButtonView( + privateBrowsingButton, + browsingModeManager + ) { newMode -> invokePendingDeleteJobs() - val invertedMode = BrowsingMode.fromBoolean(!browsingModeManager.mode.isPrivate) if (onboarding.userHasBeenOnboarded()) { getManagedEmitter().onNext( - SessionControlChange.ModeChange(Mode.fromBrowsingMode(invertedMode)) + SessionControlChange.ModeChange(Mode.fromBrowsingMode(newMode)) ) } - - browsingModeManager.mode = invertedMode } // We need the shadow to be above the components. diff --git a/app/src/main/java/org/mozilla/fenix/home/PrivateBrowsingButtonView.kt b/app/src/main/java/org/mozilla/fenix/home/PrivateBrowsingButtonView.kt new file mode 100644 index 000000000..3c6aed271 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/home/PrivateBrowsingButtonView.kt @@ -0,0 +1,48 @@ +/* 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.home + +import android.view.View +import androidx.annotation.StringRes +import org.mozilla.fenix.BrowsingMode +import org.mozilla.fenix.BrowsingModeManager +import org.mozilla.fenix.R + +/** + * Sets up the private browsing toggle button on the [HomeFragment]. + */ +class PrivateBrowsingButtonView( + button: View, + private val browsingModeManager: BrowsingModeManager, + private val onClick: (BrowsingMode) -> Unit +) : View.OnClickListener { + + init { + button.contentDescription = button.context.getString(getContentDescription(browsingModeManager.mode)) + button.setOnClickListener(this) + } + + /** + * Calls [onClick] with the new [BrowsingMode] and updates the [browsingModeManager]. + */ + override fun onClick(v: View) { + val invertedMode = BrowsingMode.fromBoolean(!browsingModeManager.mode.isPrivate) + onClick(invertedMode) + + browsingModeManager.mode = invertedMode + } + + companion object { + + /** + * Returns the appropriate content description depending on the browsing mode. + */ + @StringRes + private fun getContentDescription(mode: BrowsingMode) = when (mode) { + BrowsingMode.Normal -> R.string.content_description_private_browsing_button + BrowsingMode.Private -> R.string.content_description_disable_private_browsing_button + } + } +} diff --git a/app/src/test/java/org/mozilla/fenix/home/PrivateBrowsingButtonViewTest.kt b/app/src/test/java/org/mozilla/fenix/home/PrivateBrowsingButtonViewTest.kt new file mode 100644 index 000000000..3dad8fcd4 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/home/PrivateBrowsingButtonViewTest.kt @@ -0,0 +1,73 @@ +/* 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.home + +import android.view.View +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test +import org.mozilla.fenix.BrowsingMode +import org.mozilla.fenix.BrowsingModeManager +import org.mozilla.fenix.R + +class PrivateBrowsingButtonViewTest { + + private val enable = "Enable private browsing" + private val disable = "Disable private browsing" + + private lateinit var button: View + private lateinit var browsingModeManager: BrowsingModeManager + + @Before + fun setup() { + button = mockk(relaxed = true) + browsingModeManager = mockk(relaxed = true) + + every { button.context.getString(R.string.content_description_private_browsing_button) } returns enable + every { button.context.getString(R.string.content_description_disable_private_browsing_button) } returns disable + every { browsingModeManager.mode } returns BrowsingMode.Normal + } + + @Test + fun `constructor sets contentDescription and click listener`() { + val view = PrivateBrowsingButtonView(button, browsingModeManager) {} + verify { button.context.getString(R.string.content_description_private_browsing_button) } + verify { button.contentDescription = enable } + verify { button.setOnClickListener(view) } + + every { browsingModeManager.mode } returns BrowsingMode.Private + val privateView = PrivateBrowsingButtonView(button, browsingModeManager) {} + verify { button.context.getString(R.string.content_description_disable_private_browsing_button) } + verify { button.contentDescription = disable } + verify { button.setOnClickListener(privateView) } + } + + @Test + fun `click listener calls onClick with inverted mode from normal mode`() { + every { browsingModeManager.mode } returns BrowsingMode.Normal + var mode: BrowsingMode? = null + val view = PrivateBrowsingButtonView(button, browsingModeManager) { mode = it } + + view.onClick(button) + + assertEquals(BrowsingMode.Private, mode) + verify { browsingModeManager.mode = BrowsingMode.Private } + } + + @Test + fun `click listener calls onClick with inverted mode from private mode`() { + every { browsingModeManager.mode } returns BrowsingMode.Private + var mode: BrowsingMode? = null + val view = PrivateBrowsingButtonView(button, browsingModeManager) { mode = it } + + view.onClick(button) + + assertEquals(BrowsingMode.Normal, mode) + verify { browsingModeManager.mode = BrowsingMode.Normal } + } +}