tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit f320908698fa6febcb43357ef3155a8988d65b40
parent 2c67a14f5a0a94e346e7acc14abb356ac53827b7
Author: mcarare <48995920+mcarare@users.noreply.github.com>
Date:   Mon,  3 Nov 2025 08:05:39 +0000

Bug 1996630 - Inject Settings into TrackingProtectionPanelView. r=android-reviewers,avirvara,anpopa

This patch refactors `TrackingProtectionPanelView` to receive a `Settings` object via its constructor instead of accessing it through a `Context` extension function.

This change improves testability by allowing a mocked `Settings` object to be injected directly, removing the need for `mockkStatic` in `TrackingProtectionPanelViewTest`.

Differential Revision: https://phabricator.services.mozilla.com/D270863

Diffstat:
Mmobile/android/fenix/app/lint-baseline.xml | 55-------------------------------------------------------
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelDialogFragment.kt | 7++++++-
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelView.kt | 7++++---
Mmobile/android/fenix/app/src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelViewTest.kt | 115++++++++++++++++++++++++++++++++++---------------------------------------------
4 files changed, 59 insertions(+), 125 deletions(-)

diff --git a/mobile/android/fenix/app/lint-baseline.xml b/mobile/android/fenix/app/lint-baseline.xml @@ -378,61 +378,6 @@ <issue id="NoStaticMocking" message="Usage of MockK&apos;s &apos;mockkStatic&apos; for static mocking is discouraged. Refactor to use dependency injection." - errorLine1=" mockkStatic(&quot;org.mozilla.fenix.ext.ContextKt&quot;) {" - errorLine2=" ^"> - <location - file="src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelViewTest.kt" - line="62" - column="9"/> - </issue> - - <issue - id="NoStaticMocking" - message="Usage of MockK&apos;s &apos;mockkStatic&apos; for static mocking is discouraged. Refactor to use dependency injection." - errorLine1=" mockkStatic(&quot;org.mozilla.fenix.ext.ContextKt&quot;) {" - errorLine2=" ^"> - <location - file="src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelViewTest.kt" - line="76" - column="9"/> - </issue> - - <issue - id="NoStaticMocking" - message="Usage of MockK&apos;s &apos;mockkStatic&apos; for static mocking is discouraged. Refactor to use dependency injection." - errorLine1=" mockkStatic(&quot;org.mozilla.fenix.ext.ContextKt&quot;) {" - errorLine2=" ^"> - <location - file="src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelViewTest.kt" - line="91" - column="9"/> - </issue> - - <issue - id="NoStaticMocking" - message="Usage of MockK&apos;s &apos;mockkStatic&apos; for static mocking is discouraged. Refactor to use dependency injection." - errorLine1=" mockkStatic(&quot;org.mozilla.fenix.ext.ContextKt&quot;) {" - errorLine2=" ^"> - <location - file="src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelViewTest.kt" - line="132" - column="9"/> - </issue> - - <issue - id="NoStaticMocking" - message="Usage of MockK&apos;s &apos;mockkStatic&apos; for static mocking is discouraged. Refactor to use dependency injection." - errorLine1=" mockkStatic(&quot;org.mozilla.fenix.ext.ContextKt&quot;) {" - errorLine2=" ^"> - <location - file="src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelViewTest.kt" - line="155" - column="9"/> - </issue> - - <issue - id="NoStaticMocking" - message="Usage of MockK&apos;s &apos;mockkStatic&apos; for static mocking is discouraged. Refactor to use dependency injection." errorLine1=" mockkStatic(&quot;mozilla.components.support.ktx.android.util.DisplayMetricsKt&quot;)" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelDialogFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelDialogFragment.kt @@ -48,6 +48,7 @@ import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.databinding.FragmentTrackingProtectionBinding import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.requireComponents +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.settings.SupportUtils import com.google.android.material.R as materialR @@ -116,7 +117,11 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), UserInt ) val binding = FragmentTrackingProtectionBinding.bind(view) trackingProtectionView = - TrackingProtectionPanelView(binding.fragmentTp, trackingProtectionInteractor) + TrackingProtectionPanelView( + containerView = binding.fragmentTp, + settings = requireContext().settings(), + interactor = trackingProtectionInteractor, + ) tab?.let { updateTrackers(it) } return view } diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelView.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelView.kt @@ -25,7 +25,6 @@ import org.mozilla.fenix.GleanMetrics.TrackingProtection import org.mozilla.fenix.R import org.mozilla.fenix.databinding.ComponentTrackingProtectionPanelBinding import org.mozilla.fenix.ext.addUnderline -import org.mozilla.fenix.ext.settings import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CROSS_SITE_TRACKING_COOKIES import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CRYPTOMINERS import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.FINGERPRINTERS @@ -33,6 +32,7 @@ import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.REDIRECT_ import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.SOCIAL_MEDIA_TRACKERS import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.SUSPECTED_FINGERPRINTERS import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.TRACKING_CONTENT +import org.mozilla.fenix.utils.Settings /** * Interface for the TrackingProtectionPanelViewInteractor. This interface is implemented by objects that want @@ -73,6 +73,7 @@ interface TrackingProtectionPanelViewInteractor { @SuppressWarnings("TooManyFunctions") class TrackingProtectionPanelView( val containerView: ViewGroup, + val settings: Settings, val interactor: TrackingProtectionPanelInteractor, ) : View.OnClickListener { @@ -133,7 +134,7 @@ class TrackingProtectionPanelView( binding.notBlockingHeader.isGone = bucketedTrackers.loadedIsEmpty() binding.blockingHeader.isGone = bucketedTrackers.blockedIsEmpty() - if (containerView.context.settings().enabledTotalCookieProtection) { + if (settings.enabledTotalCookieProtection) { binding.crossSiteTracking.text = containerView.context.getString(R.string.etp_cookies_title_2) binding.crossSiteTrackingLoaded.text = containerView.context.getString(R.string.etp_cookies_title_2) } @@ -151,7 +152,7 @@ class TrackingProtectionPanelView( binding.detailsMode.visibility = View.VISIBLE if (category == CROSS_SITE_TRACKING_COOKIES && - containerView.context.settings().enabledTotalCookieProtection + settings.enabledTotalCookieProtection ) { binding.categoryTitle.setText(R.string.etp_cookies_title_2) binding.categoryDescription.setText(R.string.etp_cookies_description_2) diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelViewTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelViewTest.kt @@ -4,13 +4,11 @@ package org.mozilla.fenix.trackingprotection -import android.content.Context import android.view.ViewGroup import android.widget.FrameLayout import androidx.core.view.isVisible import io.mockk.every import io.mockk.mockk -import io.mockk.mockkStatic import io.mockk.verify import mozilla.components.support.test.robolectric.testContext import org.junit.Assert.assertEquals @@ -25,16 +23,17 @@ import org.junit.runner.RunWith import org.mozilla.fenix.GleanMetrics.TrackingProtection import org.mozilla.fenix.R import org.mozilla.fenix.ext.components -import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.FenixGleanTestRule import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CROSS_SITE_TRACKING_COOKIES import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.SOCIAL_MEDIA_TRACKERS +import org.mozilla.fenix.utils.Settings import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) class TrackingProtectionPanelViewTest { private lateinit var container: ViewGroup + private lateinit var settings: Settings private lateinit var interactor: TrackingProtectionPanelInteractor private lateinit var view: TrackingProtectionPanelView private val baseState = ProtectionsState( @@ -54,51 +53,42 @@ class TrackingProtectionPanelViewTest { fun setup() { container = FrameLayout(testContext) interactor = mockk(relaxUnitFun = true) - view = TrackingProtectionPanelView(container, interactor) + settings = mockk(relaxed = true) + view = TrackingProtectionPanelView(container, settings = settings, interactor) } @Test fun testNormalModeUi() { - mockkStatic("org.mozilla.fenix.ext.ContextKt") { - every { any<Context>().settings() } returns mockk(relaxed = true) - - view.update(baseState.copy(mode = ProtectionsState.Mode.Normal)) - assertFalse(view.binding.detailsMode.isVisible) - assertTrue(view.binding.normalMode.isVisible) - assertTrue(view.binding.protectionSettings.isVisible) - assertFalse(view.binding.notBlockingHeader.isVisible) - assertFalse(view.binding.blockingHeader.isVisible) - } + view.update(baseState.copy(mode = ProtectionsState.Mode.Normal)) + assertFalse(view.binding.detailsMode.isVisible) + assertTrue(view.binding.normalMode.isVisible) + assertTrue(view.binding.protectionSettings.isVisible) + assertFalse(view.binding.notBlockingHeader.isVisible) + assertFalse(view.binding.blockingHeader.isVisible) } @Test fun testNormalModeUiCookiesWithTotalCookieProtectionEnabled() { - mockkStatic("org.mozilla.fenix.ext.ContextKt") { - every { any<Context>().settings() } returns mockk { - every { enabledTotalCookieProtection } returns true - } - val expectedTitle = testContext.getString(R.string.etp_cookies_title_2) + every { settings.enabledTotalCookieProtection } returns true - view.update(baseState.copy(mode = ProtectionsState.Mode.Normal)) + val expectedTitle = testContext.getString(R.string.etp_cookies_title_2) - assertEquals(expectedTitle, view.binding.crossSiteTracking.text) - assertEquals(expectedTitle, view.binding.crossSiteTrackingLoaded.text) - } + view.update(baseState.copy(mode = ProtectionsState.Mode.Normal)) + + assertEquals(expectedTitle, view.binding.crossSiteTracking.text) + assertEquals(expectedTitle, view.binding.crossSiteTrackingLoaded.text) } @Test fun testNormalModeUiCookiesWithTotalCookieProtectionDisabled() { - mockkStatic("org.mozilla.fenix.ext.ContextKt") { - every { any<Context>().settings() } returns mockk { - every { enabledTotalCookieProtection } returns false - } - val expectedTitle = testContext.getString(R.string.etp_cookies_title) + every { settings.enabledTotalCookieProtection } returns false + + val expectedTitle = testContext.getString(R.string.etp_cookies_title) - view.update(baseState.copy(mode = ProtectionsState.Mode.Normal)) + view.update(baseState.copy(mode = ProtectionsState.Mode.Normal)) - assertEquals(expectedTitle, view.binding.crossSiteTracking.text) - assertEquals(expectedTitle, view.binding.crossSiteTrackingLoaded.text) - } + assertEquals(expectedTitle, view.binding.crossSiteTracking.text) + assertEquals(expectedTitle, view.binding.crossSiteTrackingLoaded.text) } @Test @@ -129,48 +119,41 @@ class TrackingProtectionPanelViewTest { @Test fun testPrivateModeUiCookiesWithTotalCookieProtectionEnabled() { - mockkStatic("org.mozilla.fenix.ext.ContextKt") { - every { any<Context>().settings() } returns mockk { - every { enabledTotalCookieProtection } returns true - } - val expectedTitle = testContext.getString(R.string.etp_cookies_title_2) - val expectedDescription = testContext.getString(R.string.etp_cookies_description_2) - - view.update( - baseState.copy( - mode = ProtectionsState.Mode.Details( - selectedCategory = CROSS_SITE_TRACKING_COOKIES, - categoryBlocked = false, - ), + every { settings.enabledTotalCookieProtection } returns true + val expectedTitle = testContext.getString(R.string.etp_cookies_title_2) + val expectedDescription = testContext.getString(R.string.etp_cookies_description_2) + + view.update( + baseState.copy( + mode = ProtectionsState.Mode.Details( + selectedCategory = CROSS_SITE_TRACKING_COOKIES, + categoryBlocked = false, ), - ) + ), + ) - assertEquals(expectedTitle, view.binding.categoryTitle.text) - assertEquals(expectedDescription, view.binding.categoryDescription.text) - } + assertEquals(expectedTitle, view.binding.categoryTitle.text) + assertEquals(expectedDescription, view.binding.categoryDescription.text) } @Test fun testPrivateModeUiCookiesWithTotalCookieProtectionDisabled() { - mockkStatic("org.mozilla.fenix.ext.ContextKt") { - every { any<Context>().settings() } returns mockk { - every { enabledTotalCookieProtection } returns false - } - val expectedTitle = testContext.getString(R.string.etp_cookies_title) - val expectedDescription = testContext.getString(R.string.etp_cookies_description) - - view.update( - baseState.copy( - mode = ProtectionsState.Mode.Details( - selectedCategory = CROSS_SITE_TRACKING_COOKIES, - categoryBlocked = false, - ), + every { settings.enabledTotalCookieProtection } returns false + + val expectedTitle = testContext.getString(R.string.etp_cookies_title) + val expectedDescription = testContext.getString(R.string.etp_cookies_description) + + view.update( + baseState.copy( + mode = ProtectionsState.Mode.Details( + selectedCategory = CROSS_SITE_TRACKING_COOKIES, + categoryBlocked = false, ), - ) + ), + ) - assertEquals(expectedTitle, view.binding.categoryTitle.text) - assertEquals(expectedDescription, view.binding.categoryDescription.text) - } + assertEquals(expectedTitle, view.binding.categoryTitle.text) + assertEquals(expectedDescription, view.binding.categoryDescription.text) } @Test