[fenix] For https://github.com/mozilla-mobile/fenix/issues/18175 - Add a new total protection ETP cookies policy

This should only add the new option in settings based on a Nimbus experiment.
pull/600/head
Mugurell 3 years ago committed by mergify[bot]
parent 19bcd56a09
commit 733dce16d6

@ -219,7 +219,7 @@ private fun assertCustomTrackingProtectionSettings() {
private fun cookiesCheckbox() = onView(withText("Cookies")) private fun cookiesCheckbox() = onView(withText("Cookies"))
private fun cookiesDropDownMenuDefault() = onView(withText("Cross-site and social media trackers")) private fun cookiesDropDownMenuDefault() = onView(withText("Isolate cross-site cookies"))
private fun trackingContentCheckbox() = onView(withText("Tracking content")) private fun trackingContentCheckbox() = onView(withText("Tracking content"))

@ -78,6 +78,7 @@ class TrackingProtectionPolicyFactory(
resources.getString(R.string.social) -> CookiePolicy.ACCEPT_NON_TRACKERS resources.getString(R.string.social) -> CookiePolicy.ACCEPT_NON_TRACKERS
resources.getString(R.string.unvisited) -> CookiePolicy.ACCEPT_VISITED resources.getString(R.string.unvisited) -> CookiePolicy.ACCEPT_VISITED
resources.getString(R.string.third_party) -> CookiePolicy.ACCEPT_ONLY_FIRST_PARTY resources.getString(R.string.third_party) -> CookiePolicy.ACCEPT_ONLY_FIRST_PARTY
resources.getString(R.string.total_protection) -> CookiePolicy.ACCEPT_FIRST_PARTY_AND_ISOLATE_OTHERS
else -> CookiePolicy.ACCEPT_NONE else -> CookiePolicy.ACCEPT_NONE
} }
} }

@ -0,0 +1,47 @@
/* 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.settings
import android.content.Context
import android.util.AttributeSet
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.settings
/**
* Custom [DropDownListPreference] that automatically builds the list of available options for the
* custom Enhanced Tracking Protection option depending on the current Nimbus experiments.
*/
class CustomEtpCookiesOptionsDropDownListPreference @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : DropDownListPreference(context, attrs) {
init {
with(context) {
entries = arrayOf(
getString(R.string.preference_enhanced_tracking_protection_custom_cookies_1),
getString(R.string.preference_enhanced_tracking_protection_custom_cookies_2),
getString(R.string.preference_enhanced_tracking_protection_custom_cookies_3),
getString(R.string.preference_enhanced_tracking_protection_custom_cookies_4),
)
entryValues = arrayOf(
getString(R.string.social),
getString(R.string.unvisited),
getString(R.string.third_party),
getString(R.string.all),
)
@Suppress("UNCHECKED_CAST")
if (context.settings().enabledTotalCookieProtectionSetting) {
// If the new "Total cookie protection" should be shown it must be first item.
entries = arrayOf(getString(R.string.preference_enhanced_tracking_protection_custom_cookies_5)) +
entries as Array<String>
entryValues = arrayOf(getString(R.string.total_protection)) + entryValues as Array<String>
}
}
setDefaultValue(entryValues.first())
}
}

@ -11,7 +11,7 @@ import androidx.preference.DropDownPreference
import androidx.preference.ListPreference import androidx.preference.ListPreference
import org.mozilla.fenix.R import org.mozilla.fenix.R
class DropDownListPreference @JvmOverloads constructor( open class DropDownListPreference @JvmOverloads constructor(
context: Context, context: Context,
attrs: AttributeSet? = null attrs: AttributeSet? = null
) : DropDownPreference(context, attrs) { ) : DropDownPreference(context, attrs) {

@ -6,6 +6,7 @@ package org.mozilla.fenix.trackingprotection
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.annotation.VisibleForTesting
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
@ -19,11 +20,22 @@ class TrackingProtectionBlockingFragment :
private val args: TrackingProtectionBlockingFragmentArgs by navArgs() private val args: TrackingProtectionBlockingFragmentArgs by navArgs()
private val settings by lazy { requireContext().settings() } private val settings by lazy { requireContext().settings() }
@VisibleForTesting
internal lateinit var binding: FragmentTrackingProtectionBlockingBinding
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val binding = FragmentTrackingProtectionBlockingBinding.bind(view) binding = FragmentTrackingProtectionBlockingBinding.bind(view)
// Text for the updated "Total cookie protection" option should be updated as part of a staged rollout
if (requireContext().settings().enabledTotalCookieProtectionSetting) {
binding.categoryCookies.apply {
trackingProtectionCategoryTitle.text = getText(R.string.etp_cookies_title_2)
trackingProtectionCategoryItemDescription.text = getText(R.string.etp_cookies_description_2)
}
}
when (args.protectionMode) { when (args.protectionMode) {
TrackingProtectionMode.STANDARD -> { TrackingProtectionMode.STANDARD -> {
binding.categoryTrackingContent.isVisible = false binding.categoryTrackingContent.isVisible = false

@ -17,12 +17,12 @@ class TrackingProtectionCategoryItem @JvmOverloads constructor(
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyleAttr: Int = 0 defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) { ) : ConstraintLayout(context, attrs, defStyleAttr) {
init { private val binding = TrackingProtectionCategoryBinding.inflate(
val binding = TrackingProtectionCategoryBinding.inflate(
LayoutInflater.from(context), LayoutInflater.from(context),
this this
) )
init {
context.withStyledAttributes( context.withStyledAttributes(
attrs, attrs,
R.styleable.TrackingProtectionCategory, R.styleable.TrackingProtectionCategory,
@ -43,4 +43,14 @@ class TrackingProtectionCategoryItem @JvmOverloads constructor(
) )
} }
} }
/**
* The displayed title of this item.
*/
val trackingProtectionCategoryTitle = binding.trackingProtectionCategoryTitle
/**
* The displayed description of this item.
*/
val trackingProtectionCategoryItemDescription = binding.trackingProtectionCategoryItemDescription
} }

@ -25,6 +25,7 @@ import org.mozilla.fenix.GleanMetrics.TrackingProtection
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.ComponentTrackingProtectionPanelBinding import org.mozilla.fenix.databinding.ComponentTrackingProtectionPanelBinding
import org.mozilla.fenix.ext.addUnderline 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.CROSS_SITE_TRACKING_COOKIES
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CRYPTOMINERS import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CRYPTOMINERS
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.FINGERPRINTERS import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.FINGERPRINTERS
@ -128,6 +129,11 @@ class TrackingProtectionPanelView(
binding.notBlockingHeader.isGone = bucketedTrackers.loadedIsEmpty() binding.notBlockingHeader.isGone = bucketedTrackers.loadedIsEmpty()
binding.blockingHeader.isGone = bucketedTrackers.blockedIsEmpty() binding.blockingHeader.isGone = bucketedTrackers.blockedIsEmpty()
if (containerView.context.settings().enabledTotalCookieProtectionSetting) {
binding.crossSiteTracking.text = containerView.context.getString(R.string.etp_cookies_title_2)
binding.crossSiteTrackingLoaded.text = containerView.context.getString(R.string.etp_cookies_title_2)
}
updateCategoryVisibility() updateCategoryVisibility()
focusAccessibilityLastUsedCategory(state.lastAccessedCategory) focusAccessibilityLastUsedCategory(state.lastAccessedCategory)
} }
@ -139,7 +145,16 @@ class TrackingProtectionPanelView(
val containASmartBlockItem = bucketedTrackers.get(category, categoryBlocked).any { it.unBlockedBySmartBlock } val containASmartBlockItem = bucketedTrackers.get(category, categoryBlocked).any { it.unBlockedBySmartBlock }
binding.normalMode.visibility = View.GONE binding.normalMode.visibility = View.GONE
binding.detailsMode.visibility = View.VISIBLE binding.detailsMode.visibility = View.VISIBLE
if (category == CROSS_SITE_TRACKING_COOKIES &&
containerView.context.settings().enabledTotalCookieProtectionSetting
) {
binding.categoryTitle.setText(R.string.etp_cookies_title_2)
binding.categoryDescription.setText(R.string.etp_cookies_description_2)
} else {
binding.categoryTitle.setText(category.title) binding.categoryTitle.setText(category.title)
binding.categoryDescription.setText(category.description)
}
binding.smartblockDescription.isVisible = containASmartBlockItem binding.smartblockDescription.isVisible = containASmartBlockItem
binding.smartblockLearnMore.isVisible = containASmartBlockItem binding.smartblockLearnMore.isVisible = containASmartBlockItem
@ -158,7 +173,7 @@ class TrackingProtectionPanelView(
setOnClickListener { interactor.onLearnMoreClicked() } setOnClickListener { interactor.onLearnMoreClicked() }
} }
} }
binding.categoryDescription.setText(category.description)
binding.detailsBlockingHeader.setText( binding.detailsBlockingHeader.setText(
if (categoryBlocked) { if (categoryBlocked) {
R.string.enhanced_tracking_protection_blocked R.string.enhanced_tracking_protection_blocked

@ -571,9 +571,16 @@ class Settings(private val appContext: Context) : PreferencesHolder {
val enabledTotalCookieProtection: Boolean val enabledTotalCookieProtection: Boolean
get() = FxNimbus.features.engineSettings.value().totalCookieProtectionEnabled get() = FxNimbus.features.engineSettings.value().totalCookieProtectionEnabled
val enabledTotalCookieProtectionSetting: Boolean
get() = mr2022Sections[Mr2022Section.TCP_CFR] == true
val blockCookiesSelectionInCustomTrackingProtection by stringPreference( val blockCookiesSelectionInCustomTrackingProtection by stringPreference(
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_custom_cookies_select), key = appContext.getPreferenceKey(R.string.pref_key_tracking_protection_custom_cookies_select),
default = if (enabledTotalCookieProtectionSetting) {
appContext.getString(R.string.total_protection)
} else {
appContext.getString(R.string.social) appContext.getString(R.string.social)
}
) )
val blockTrackingContentInCustomTrackingProtection by booleanPreference( val blockTrackingContentInCustomTrackingProtection by booleanPreference(

@ -3,6 +3,7 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this - 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/. --> - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<resources> <resources>
<string name="total_protection">total-protection</string>
<string name="social">social</string> <string name="social">social</string>
<string name="unvisited">unvisited</string> <string name="unvisited">unvisited</string>
<string name="third_party">third-party</string> <string name="third_party">third-party</string>
@ -10,6 +11,7 @@
<string name="private_string">private</string> <string name="private_string">private</string>
<string-array name="cookies_options_entries"> <string-array name="cookies_options_entries">
<item>@string/preference_enhanced_tracking_protection_custom_cookies_5</item>
<item>@string/preference_enhanced_tracking_protection_custom_cookies_1</item> <item>@string/preference_enhanced_tracking_protection_custom_cookies_1</item>
<item>@string/preference_enhanced_tracking_protection_custom_cookies_2</item> <item>@string/preference_enhanced_tracking_protection_custom_cookies_2</item>
<item>@string/preference_enhanced_tracking_protection_custom_cookies_3</item> <item>@string/preference_enhanced_tracking_protection_custom_cookies_3</item>
@ -17,6 +19,7 @@
</string-array> </string-array>
<string-array name="cookies_options_entry_values"> <string-array name="cookies_options_entry_values">
<item>@string/total_protection</item>
<item>@string/social</item> <item>@string/social</item>
<item>@string/unvisited</item> <item>@string/unvisited</item>
<item>@string/third_party</item> <item>@string/third_party</item>

@ -1275,6 +1275,8 @@
<string name="preference_enhanced_tracking_protection_custom_cookies_3">All third-party cookies (may cause websites to break)</string> <string name="preference_enhanced_tracking_protection_custom_cookies_3">All third-party cookies (may cause websites to break)</string>
<!-- Option for enhanced tracking protection for the custom protection settings for cookies--> <!-- Option for enhanced tracking protection for the custom protection settings for cookies-->
<string name="preference_enhanced_tracking_protection_custom_cookies_4">All cookies (will cause websites to break)</string> <string name="preference_enhanced_tracking_protection_custom_cookies_4">All cookies (will cause websites to break)</string>
<!-- Option for enhanced tracking protection for the custom protection settings for cookies-->
<string name="preference_enhanced_tracking_protection_custom_cookies_5">Isolate cross-site cookies</string>
<!-- Preference for enhanced tracking protection for the custom protection settings for tracking content --> <!-- Preference for enhanced tracking protection for the custom protection settings for tracking content -->
<string name="preference_enhanced_tracking_protection_custom_tracking_content">Tracking content</string> <string name="preference_enhanced_tracking_protection_custom_tracking_content">Tracking content</string>
<!-- Option for enhanced tracking protection for the custom protection settings for tracking content--> <!-- Option for enhanced tracking protection for the custom protection settings for tracking content-->
@ -1297,8 +1299,12 @@
<string name="etp_social_media_trackers_description">Limits the ability of social networks to track your browsing activity around the web.</string> <string name="etp_social_media_trackers_description">Limits the ability of social networks to track your browsing activity around the web.</string>
<!-- Category of trackers (cross-site tracking cookies) that can be blocked by Enhanced Tracking Protection --> <!-- Category of trackers (cross-site tracking cookies) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_cookies_title">Cross-Site Tracking Cookies</string> <string name="etp_cookies_title">Cross-Site Tracking Cookies</string>
<!-- Category of trackers (cross-site tracking cookies) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_cookies_title_2">Cross-Site Cookies</string>
<!-- Description of cross-site tracking cookies that can be blocked by Enhanced Tracking Protection --> <!-- Description of cross-site tracking cookies that can be blocked by Enhanced Tracking Protection -->
<string name="etp_cookies_description">Blocks cookies that ad networks and analytics companies use to compile your browsing data across many sites.</string> <string name="etp_cookies_description">Blocks cookies that ad networks and analytics companies use to compile your browsing data across many sites.</string>
<!-- Description of cross-site tracking cookies that can be blocked by Enhanced Tracking Protection -->
<string name="etp_cookies_description_2">Total Cookie Protection isolates cookies to the site you\'re on so trackers like ad networks can\'t use them to follow you across sites.</string>
<!-- Category of trackers (cryptominers) that can be blocked by Enhanced Tracking Protection --> <!-- Category of trackers (cryptominers) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_cryptominers_title">Cryptominers</string> <string name="etp_cryptominers_title">Cryptominers</string>
<!-- Description of cryptominers that can be blocked by Enhanced Tracking Protection --> <!-- Description of cryptominers that can be blocked by Enhanced Tracking Protection -->

@ -38,7 +38,7 @@
android:key="@string/pref_key_tracking_protection_custom_cookies" android:key="@string/pref_key_tracking_protection_custom_cookies"
android:layout="@layout/checkbox_left_preference_etp" android:layout="@layout/checkbox_left_preference_etp"
android:title="@string/preference_enhanced_tracking_protection_custom_cookies" /> android:title="@string/preference_enhanced_tracking_protection_custom_cookies" />
<org.mozilla.fenix.settings.DropDownListPreference <org.mozilla.fenix.settings.CustomEtpCookiesOptionsDropDownListPreference
android:defaultValue="@string/social" android:defaultValue="@string/social"
android:dependency="@string/pref_key_tracking_protection_custom_cookies" android:dependency="@string/pref_key_tracking_protection_custom_cookies"
android:entries="@array/cookies_options_entries" android:entries="@array/cookies_options_entries"

@ -253,6 +253,30 @@ class TrackingProtectionPolicyFactoryTest {
expected.assertPolicyEquals(always, checkPrivacy = false) expected.assertPolicyEquals(always, checkPrivacy = false)
} }
@Test
fun `GIVEN custom policy WHEN cookie policy is total protection THEN tracking policy should have cookie policy to block cross-site cookies`() {
val expected = TrackingProtectionPolicy.select(
cookiePolicy = TrackingProtectionPolicy.CookiePolicy.ACCEPT_FIRST_PARTY_AND_ISOLATE_OTHERS,
trackingCategories = allTrackingCategories
)
val factory = TrackingProtectionPolicyFactory(
settingsForCustom(
shouldBlockCookiesInCustom = true,
blockCookiesSelection = "total-protection"
),
testContext.resources
)
val privateOnly = factory.createTrackingProtectionPolicy(normalMode = false, privateMode = true)
val normalOnly = factory.createTrackingProtectionPolicy(normalMode = true, privateMode = false)
val always = factory.createTrackingProtectionPolicy(normalMode = true, privateMode = true)
expected.assertPolicyEquals(privateOnly, checkPrivacy = false)
expected.assertPolicyEquals(normalOnly, checkPrivacy = false)
expected.assertPolicyEquals(always, checkPrivacy = false)
}
@Test @Test
fun `GIVEN custom policy WHEN cookie policy unrecognized THEN tracking policy should have cookie policy block all`() { fun `GIVEN custom policy WHEN cookie policy unrecognized THEN tracking policy should have cookie policy block all`() {
val expected = TrackingProtectionPolicy.select( val expected = TrackingProtectionPolicy.select(

@ -0,0 +1,86 @@
/* 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.settings
import android.content.Context
import androidx.preference.Preference
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@RunWith(FenixRobolectricTestRunner::class)
class CustomEtpCookiesOptionsDropDownListPreferenceTest {
@Test
fun `GIVEN total cookie protection is enabled WHEN using this preference THEN show the total cookie protection option`() {
val expectedEntries = arrayOf(
testContext.getString(R.string.preference_enhanced_tracking_protection_custom_cookies_5)
) + defaultEntries
val expectedValues = arrayOf(testContext.getString(R.string.total_protection)) + defaultValues
mockkStatic("org.mozilla.fenix.ext.ContextKt") {
every { any<Context>().settings() } returns mockk {
every { enabledTotalCookieProtectionSetting } returns true
}
val preference = CustomEtpCookiesOptionsDropDownListPreference(testContext)
assertArrayEquals(expectedEntries, preference.entries)
assertArrayEquals(expectedValues, preference.entryValues)
assertEquals(expectedValues[0], preference.getDefaultValue())
}
}
@Test
fun `GIVEN total cookie protection is disabled WHEN using this preference THEN don't show the total cookie protection option`() {
mockkStatic("org.mozilla.fenix.ext.ContextKt") {
every { any<Context>().settings() } returns mockk {
every { enabledTotalCookieProtectionSetting } returns false
}
val preference = CustomEtpCookiesOptionsDropDownListPreference(testContext)
assertArrayEquals(defaultEntries, preference.entries)
assertArrayEquals(defaultValues, preference.entryValues)
assertEquals(defaultValues[0], preference.getDefaultValue())
}
}
/**
* Use reflection to get the private member holding the default value set for this preference.
*/
private fun CustomEtpCookiesOptionsDropDownListPreference.getDefaultValue(): String {
return Preference::class.java
.getDeclaredField("mDefaultValue").let { field ->
field.isAccessible = true
return@let field.get(this) as String
}
}
private val defaultEntries = with(testContext) {
arrayOf(
getString(R.string.preference_enhanced_tracking_protection_custom_cookies_1),
getString(R.string.preference_enhanced_tracking_protection_custom_cookies_2),
getString(R.string.preference_enhanced_tracking_protection_custom_cookies_3),
getString(R.string.preference_enhanced_tracking_protection_custom_cookies_4),
)
}
private val defaultValues = with(testContext) {
arrayOf(
getString(R.string.social),
getString(R.string.unvisited),
getString(R.string.third_party),
getString(R.string.all),
)
}
}

@ -0,0 +1,79 @@
/* 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.trackingprotection
import android.content.Context
import androidx.fragment.app.FragmentActivity
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.trackingprotection.TrackingProtectionMode.CUSTOM
import org.robolectric.Robolectric
@RunWith(FenixRobolectricTestRunner::class)
class TrackingProtectionBlockingFragmentTest {
@Test
fun `GIVEN total cookie protection is enabled WHEN showing details about the protection options THEN show update details for tracking protection`() {
val expectedTitle = testContext.getString(R.string.etp_cookies_title_2)
val expectedDescription = testContext.getString(R.string.etp_cookies_description_2)
mockkStatic("org.mozilla.fenix.ext.ContextKt") {
every { any<Context>().settings() } returns mockk(relaxed = true) {
every { enabledTotalCookieProtectionSetting } returns true
}
val fragment = createFragment()
val cookiesCategory = fragment.binding.categoryCookies
assertEquals(expectedTitle, cookiesCategory.trackingProtectionCategoryTitle.text)
assertEquals(expectedDescription, cookiesCategory.trackingProtectionCategoryItemDescription.text)
}
}
@Test
fun `GIVEN total cookie protection is not enabled WHEN showing details about the protection options THEN show the default details for tracking protection`() {
val expectedTitle = testContext.getString(R.string.etp_cookies_title)
val expectedDescription = testContext.getString(R.string.etp_cookies_description)
mockkStatic("org.mozilla.fenix.ext.ContextKt") {
every { any<Context>().settings() } returns mockk(relaxed = true) {
every { enabledTotalCookieProtectionSetting } returns false
}
val fragment = createFragment()
val cookiesCategory = fragment.binding.categoryCookies
assertEquals(expectedTitle, cookiesCategory.trackingProtectionCategoryTitle.text)
assertEquals(expectedDescription, cookiesCategory.trackingProtectionCategoryItemDescription.text)
}
}
private fun createFragment(): TrackingProtectionBlockingFragment {
// Create and attach the fragment ourself instead of using "createAddedTestFragment"
// to prevent having "onResume -> showToolbar" called.
val activity = Robolectric.buildActivity(FragmentActivity::class.java)
.create()
.start()
.get()
val fragment = TrackingProtectionBlockingFragment().apply {
arguments = TrackingProtectionBlockingFragmentArgs(
protectionMode = CUSTOM
).toBundle()
}
activity.supportFragmentManager.beginTransaction()
.add(fragment, "test")
.commitNow()
return fragment
}
}

@ -4,11 +4,13 @@
package org.mozilla.fenix.trackingprotection package org.mozilla.fenix.trackingprotection
import android.content.Context
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
import androidx.core.view.isVisible import androidx.core.view.isVisible
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.verify import io.mockk.verify
import mozilla.components.service.glean.testing.GleanTestRule import mozilla.components.service.glean.testing.GleanTestRule
import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.robolectric.testContext
@ -24,6 +26,7 @@ import org.junit.runner.RunWith
import org.mozilla.fenix.GleanMetrics.TrackingProtection import org.mozilla.fenix.GleanMetrics.TrackingProtection
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CROSS_SITE_TRACKING_COOKIES import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CROSS_SITE_TRACKING_COOKIES
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.SOCIAL_MEDIA_TRACKERS import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.SOCIAL_MEDIA_TRACKERS
@ -55,6 +58,9 @@ class TrackingProtectionPanelViewTest {
@Test @Test
fun testNormalModeUi() { fun testNormalModeUi() {
mockkStatic("org.mozilla.fenix.ext.ContextKt") {
every { any<Context>().settings() } returns mockk(relaxed = true)
view.update(baseState.copy(mode = TrackingProtectionState.Mode.Normal)) view.update(baseState.copy(mode = TrackingProtectionState.Mode.Normal))
assertFalse(view.binding.detailsMode.isVisible) assertFalse(view.binding.detailsMode.isVisible)
assertTrue(view.binding.normalMode.isVisible) assertTrue(view.binding.normalMode.isVisible)
@ -62,6 +68,37 @@ class TrackingProtectionPanelViewTest {
assertFalse(view.binding.notBlockingHeader.isVisible) assertFalse(view.binding.notBlockingHeader.isVisible)
assertFalse(view.binding.blockingHeader.isVisible) assertFalse(view.binding.blockingHeader.isVisible)
} }
}
@Test
fun testNormalModeUiCookiesWithTotalCookieProtectionEnabled() {
mockkStatic("org.mozilla.fenix.ext.ContextKt") {
every { any<Context>().settings() } returns mockk {
every { enabledTotalCookieProtectionSetting } returns true
}
val expectedTitle = testContext.getString(R.string.etp_cookies_title_2)
view.update(baseState.copy(mode = TrackingProtectionState.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 { enabledTotalCookieProtectionSetting } returns false
}
val expectedTitle = testContext.getString(R.string.etp_cookies_title)
view.update(baseState.copy(mode = TrackingProtectionState.Mode.Normal))
assertEquals(expectedTitle, view.binding.crossSiteTracking.text)
assertEquals(expectedTitle, view.binding.crossSiteTrackingLoaded.text)
}
}
@Test @Test
fun testPrivateModeUi() { fun testPrivateModeUi() {
@ -89,6 +126,52 @@ class TrackingProtectionPanelViewTest {
) )
} }
@Test
fun testPrivateModeUiCookiesWithTotalCookieProtectionEnabled() {
mockkStatic("org.mozilla.fenix.ext.ContextKt") {
every { any<Context>().settings() } returns mockk {
every { enabledTotalCookieProtectionSetting } 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 = TrackingProtectionState.Mode.Details(
selectedCategory = CROSS_SITE_TRACKING_COOKIES,
categoryBlocked = false
)
)
)
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 { enabledTotalCookieProtectionSetting } 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 = TrackingProtectionState.Mode.Details(
selectedCategory = CROSS_SITE_TRACKING_COOKIES,
categoryBlocked = false
)
)
)
assertEquals(expectedTitle, view.binding.categoryTitle.text)
assertEquals(expectedDescription, view.binding.categoryDescription.text)
}
}
@Test @Test
fun testProtectionSettings() { fun testProtectionSettings() {
view.binding.protectionSettings.performClick() view.binding.protectionSettings.performClick()

Loading…
Cancel
Save