For #13812: add ETP category for redirect trackers (#15139)

* Feature flag for ETP cookie purging

* Strings for new ETP description

* Remove icons from ETP info screeen and add category for redirect trackers

* ETP policy factory tests

* Remove icons from ETP panel and add cross tracking allowed field.

* Remove icons on ETP panel. Add blocked category for redirect trackers to panel.

* Add margins to tracking protection settings
pull/149/head
Elise Richards 4 years ago committed by GitHub
parent 6781018556
commit a4ff782565
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -45,4 +45,9 @@ object FeatureFlags {
* Enables swipe to delete in bookmarks * Enables swipe to delete in bookmarks
*/ */
val bookmarkSwipeToDelete = Config.channel.isNightlyOrDebug val bookmarkSwipeToDelete = Config.channel.isNightlyOrDebug
/**
* Enables ETP cookie purging
*/
val etpCookiePurging = Config.channel.isNightlyOrDebug
} }

@ -8,6 +8,7 @@ import androidx.annotation.VisibleForTesting
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicyForSessionTypes import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicyForSessionTypes
import org.mozilla.fenix.Config import org.mozilla.fenix.Config
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.utils.Settings
/** /**
@ -102,6 +103,6 @@ internal fun TrackingProtectionPolicyForSessionTypes.adaptPolicyToChannel(): Tra
trackingCategories = trackingCategories, trackingCategories = trackingCategories,
cookiePolicy = cookiePolicy, cookiePolicy = cookiePolicy,
strictSocialTrackingProtection = strictSocialTrackingProtection, strictSocialTrackingProtection = strictSocialTrackingProtection,
cookiePurging = Config.channel.isNightlyOrDebug cookiePurging = FeatureFlags.etpCookiePurging
) )
} }

@ -10,6 +10,7 @@ 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
import kotlinx.android.synthetic.main.fragment_tracking_protection_blocking.* import kotlinx.android.synthetic.main.fragment_tracking_protection_blocking.*
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.ext.showToolbar
@ -22,6 +23,7 @@ class TrackingProtectionBlockingFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
category_redirect_trackers.isVisible = FeatureFlags.etpCookiePurging
when (args.protectionMode) { when (args.protectionMode) {
TrackingProtectionMode.STANDARD -> { TrackingProtectionMode.STANDARD -> {

@ -7,7 +7,6 @@ package org.mozilla.fenix.trackingprotection
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.withStyledAttributes import androidx.core.content.withStyledAttributes
import kotlinx.android.synthetic.main.tracking_protection_category.view.* import kotlinx.android.synthetic.main.tracking_protection_category.view.*
@ -27,11 +26,6 @@ class TrackingProtectionCategoryItem @JvmOverloads constructor(
defStyleAttr, defStyleAttr,
0 0
) { ) {
val id = getResourceId(
R.styleable.TrackingProtectionCategory_categoryItemIcon,
R.drawable.ic_cryptominers
)
trackingProtectionCategoryIcon?.background = AppCompatResources.getDrawable(context, id)
trackingProtectionCategoryTitle?.text = resources.getString( trackingProtectionCategoryTitle?.text = resources.getString(
getResourceId( getResourceId(
R.styleable.TrackingProtectionCategory_categoryItemTitle, R.styleable.TrackingProtectionCategory_categoryItemTitle,

@ -149,9 +149,14 @@ class TrackingProtectionPanelView(
} }
} }
/**
* Checks whether the permission was allowed or blocked when they were last used based on
* visibility, where "..._loaded" titles correspond to "Allowed" permissions and the other
* corresponds to "Blocked" permissions for each category.
*/
private fun getLastUsedCategoryView(categoryTitle: String) = when (categoryTitle) { private fun getLastUsedCategoryView(categoryTitle: String) = when (categoryTitle) {
CROSS_SITE_TRACKING_COOKIES.name -> { CROSS_SITE_TRACKING_COOKIES.name -> {
cross_site_tracking if (cross_site_tracking.isGone) cross_site_tracking_loaded else cross_site_tracking
} }
SOCIAL_MEDIA_TRACKERS.name -> { SOCIAL_MEDIA_TRACKERS.name -> {
if (social_media_trackers.isGone) social_media_trackers_loaded else social_media_trackers if (social_media_trackers.isGone) social_media_trackers_loaded else social_media_trackers
@ -171,11 +176,14 @@ class TrackingProtectionPanelView(
private fun updateCategoryVisibility() { private fun updateCategoryVisibility() {
cross_site_tracking.isGone = cross_site_tracking.isGone =
bucketedTrackers.get(CROSS_SITE_TRACKING_COOKIES, true).isEmpty() bucketedTrackers.get(CROSS_SITE_TRACKING_COOKIES, true).isEmpty()
social_media_trackers.isGone = bucketedTrackers.get(SOCIAL_MEDIA_TRACKERS, true).isEmpty() social_media_trackers.isGone =
bucketedTrackers.get(SOCIAL_MEDIA_TRACKERS, true).isEmpty()
fingerprinters.isGone = bucketedTrackers.get(FINGERPRINTERS, true).isEmpty() fingerprinters.isGone = bucketedTrackers.get(FINGERPRINTERS, true).isEmpty()
tracking_content.isGone = bucketedTrackers.get(TRACKING_CONTENT, true).isEmpty() tracking_content.isGone = bucketedTrackers.get(TRACKING_CONTENT, true).isEmpty()
cryptominers.isGone = bucketedTrackers.get(CRYPTOMINERS, true).isEmpty() cryptominers.isGone = bucketedTrackers.get(CRYPTOMINERS, true).isEmpty()
cross_site_tracking_loaded.isGone =
bucketedTrackers.get(CROSS_SITE_TRACKING_COOKIES, false).isEmpty()
social_media_trackers_loaded.isGone = social_media_trackers_loaded.isGone =
bucketedTrackers.get(SOCIAL_MEDIA_TRACKERS, false).isEmpty() bucketedTrackers.get(SOCIAL_MEDIA_TRACKERS, false).isEmpty()
fingerprinters_loaded.isGone = bucketedTrackers.get(FINGERPRINTERS, false).isEmpty() fingerprinters_loaded.isGone = bucketedTrackers.get(FINGERPRINTERS, false).isEmpty()
@ -189,6 +197,7 @@ class TrackingProtectionPanelView(
cross_site_tracking.setOnClickListener(this) cross_site_tracking.setOnClickListener(this)
tracking_content.setOnClickListener(this) tracking_content.setOnClickListener(this)
cryptominers.setOnClickListener(this) cryptominers.setOnClickListener(this)
cross_site_tracking_loaded.setOnClickListener(this)
social_media_trackers_loaded.setOnClickListener(this) social_media_trackers_loaded.setOnClickListener(this)
fingerprinters_loaded.setOnClickListener(this) fingerprinters_loaded.setOnClickListener(this)
tracking_content_loaded.setOnClickListener(this) tracking_content_loaded.setOnClickListener(this)
@ -251,7 +260,7 @@ class TrackingProtectionPanelView(
private fun getCategory(v: View) = when (v.id) { private fun getCategory(v: View) = when (v.id) {
R.id.social_media_trackers, R.id.social_media_trackers_loaded -> SOCIAL_MEDIA_TRACKERS R.id.social_media_trackers, R.id.social_media_trackers_loaded -> SOCIAL_MEDIA_TRACKERS
R.id.fingerprinters, R.id.fingerprinters_loaded -> FINGERPRINTERS R.id.fingerprinters, R.id.fingerprinters_loaded -> FINGERPRINTERS
R.id.cross_site_tracking -> CROSS_SITE_TRACKING_COOKIES R.id.cross_site_tracking, R.id.cross_site_tracking_loaded -> CROSS_SITE_TRACKING_COOKIES
R.id.tracking_content, R.id.tracking_content_loaded -> TRACKING_CONTENT R.id.tracking_content, R.id.tracking_content_loaded -> TRACKING_CONTENT
R.id.cryptominers, R.id.cryptominers_loaded -> CRYPTOMINERS R.id.cryptominers, R.id.cryptominers_loaded -> CRYPTOMINERS
else -> null else -> null
@ -262,6 +271,7 @@ class TrackingProtectionPanelView(
*/ */
private fun isLoaded(v: View) = when (v.id) { private fun isLoaded(v: View) = when (v.id) {
R.id.social_media_trackers_loaded, R.id.social_media_trackers_loaded,
R.id.cross_site_tracking_loaded,
R.id.fingerprinters_loaded, R.id.fingerprinters_loaded,
R.id.tracking_content_loaded, R.id.tracking_content_loaded,
R.id.cryptominers_loaded -> true R.id.cryptominers_loaded -> true

@ -61,7 +61,6 @@
android:layout_height="@dimen/tracking_protection_item_height" android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_cookies_title" android:text="@string/etp_cookies_title"
android:visibility="gone" android:visibility="gone"
app:drawableStartCompat="@drawable/ic_cookies"
app:layout_constraintTop_toBottomOf="@id/blocking_header" /> app:layout_constraintTop_toBottomOf="@id/blocking_header" />
<TextView <TextView
@ -71,7 +70,6 @@
android:layout_height="@dimen/tracking_protection_item_height" android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_fingerprinters_title" android:text="@string/etp_fingerprinters_title"
android:visibility="gone" android:visibility="gone"
app:drawableStartCompat="@drawable/ic_fingerprinters"
app:layout_constraintTop_toBottomOf="@id/cross_site_tracking" /> app:layout_constraintTop_toBottomOf="@id/cross_site_tracking" />
<TextView <TextView
@ -81,7 +79,6 @@
android:layout_height="@dimen/tracking_protection_item_height" android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_cryptominers_title" android:text="@string/etp_cryptominers_title"
android:visibility="gone" android:visibility="gone"
app:drawableStartCompat="@drawable/ic_cryptominers"
app:layout_constraintTop_toBottomOf="@id/fingerprinters" /> app:layout_constraintTop_toBottomOf="@id/fingerprinters" />
<TextView <TextView
@ -91,7 +88,6 @@
android:layout_height="@dimen/tracking_protection_item_height" android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_social_media_trackers_title" android:text="@string/etp_social_media_trackers_title"
android:visibility="gone" android:visibility="gone"
app:drawableStartCompat="@drawable/ic_social_media_trackers"
app:layout_constraintTop_toBottomOf="@id/cryptominers" /> app:layout_constraintTop_toBottomOf="@id/cryptominers" />
<TextView <TextView
@ -101,7 +97,6 @@
android:layout_height="@dimen/tracking_protection_item_height" android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_tracking_content_title" android:text="@string/etp_tracking_content_title"
android:visibility="gone" android:visibility="gone"
app:drawableStartCompat="@drawable/ic_tracking_content"
app:layout_constraintTop_toBottomOf="@id/social_media_trackers" /> app:layout_constraintTop_toBottomOf="@id/social_media_trackers" />
<TextView <TextView
@ -117,6 +112,15 @@
app:layout_constraintTop_toBottomOf="@id/tracking_content" app:layout_constraintTop_toBottomOf="@id/tracking_content"
tools:targetApi="p" /> tools:targetApi="p" />
<TextView
android:id="@+id/cross_site_tracking_loaded"
style="@style/QuickSettingsLargeText.Icon"
android:layout_width="match_parent"
android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_cookies_title"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/not_blocking_header" />
<TextView <TextView
android:id="@+id/fingerprinters_loaded" android:id="@+id/fingerprinters_loaded"
style="@style/QuickSettingsLargeText.Icon" style="@style/QuickSettingsLargeText.Icon"
@ -124,8 +128,7 @@
android:layout_height="@dimen/tracking_protection_item_height" android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_fingerprinters_title" android:text="@string/etp_fingerprinters_title"
android:visibility="gone" android:visibility="gone"
app:drawableStartCompat="@drawable/ic_fingerprinters" app:layout_constraintTop_toBottomOf="@id/cross_site_tracking_loaded" />
app:layout_constraintTop_toBottomOf="@id/not_blocking_header" />
<TextView <TextView
android:id="@+id/cryptominers_loaded" android:id="@+id/cryptominers_loaded"
@ -134,7 +137,6 @@
android:layout_height="@dimen/tracking_protection_item_height" android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_cryptominers_title" android:text="@string/etp_cryptominers_title"
android:visibility="gone" android:visibility="gone"
app:drawableStartCompat="@drawable/ic_cryptominers"
app:layout_constraintTop_toBottomOf="@id/fingerprinters_loaded" /> app:layout_constraintTop_toBottomOf="@id/fingerprinters_loaded" />
<TextView <TextView
@ -144,7 +146,6 @@
android:layout_height="@dimen/tracking_protection_item_height" android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_social_media_trackers_title" android:text="@string/etp_social_media_trackers_title"
android:visibility="gone" android:visibility="gone"
app:drawableStartCompat="@drawable/ic_social_media_trackers"
app:layout_constraintTop_toBottomOf="@id/cryptominers_loaded" /> app:layout_constraintTop_toBottomOf="@id/cryptominers_loaded" />
<TextView <TextView
@ -154,7 +155,6 @@
android:layout_height="@dimen/tracking_protection_item_height" android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_tracking_content_title" android:text="@string/etp_tracking_content_title"
android:visibility="gone" android:visibility="gone"
app:drawableStartCompat="@drawable/ic_tracking_content"
app:layout_constraintTop_toBottomOf="@id/social_media_trackers_loaded" /> app:layout_constraintTop_toBottomOf="@id/social_media_trackers_loaded" />
<View <View

@ -31,7 +31,6 @@
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
app:categoryItemDescription="@string/etp_social_media_trackers_description" app:categoryItemDescription="@string/etp_social_media_trackers_description"
app:categoryItemIcon="@drawable/ic_social_media_trackers"
app:categoryItemTitle="@string/etp_social_media_trackers_title" /> app:categoryItemTitle="@string/etp_social_media_trackers_title" />
<org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem <org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem
@ -42,7 +41,6 @@
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
app:categoryItemDescription="@string/etp_cookies_description" app:categoryItemDescription="@string/etp_cookies_description"
app:categoryItemIcon="@drawable/ic_cookies"
app:categoryItemTitle="@string/etp_cookies_title" /> app:categoryItemTitle="@string/etp_cookies_title" />
<org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem <org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem
@ -53,7 +51,6 @@
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
app:categoryItemDescription="@string/etp_cryptominers_description" app:categoryItemDescription="@string/etp_cryptominers_description"
app:categoryItemIcon="@drawable/ic_cryptominers"
app:categoryItemTitle="@string/etp_cryptominers_title" /> app:categoryItemTitle="@string/etp_cryptominers_title" />
<org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem <org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem
@ -64,7 +61,6 @@
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
app:categoryItemDescription="@string/etp_fingerprinters_description" app:categoryItemDescription="@string/etp_fingerprinters_description"
app:categoryItemIcon="@drawable/ic_fingerprinters"
app:categoryItemTitle="@string/etp_fingerprinters_title" /> app:categoryItemTitle="@string/etp_fingerprinters_title" />
<org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem <org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem
@ -75,7 +71,17 @@
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
app:categoryItemDescription="@string/etp_tracking_content_description" app:categoryItemDescription="@string/etp_tracking_content_description"
app:categoryItemIcon="@drawable/ic_tracking_content"
app:categoryItemTitle="@string/etp_tracking_content_title" /> app:categoryItemTitle="@string/etp_tracking_content_title" />
<org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem
android:id="@+id/category_redirect_trackers"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
app:categoryItemDescription="@string/etp_redirect_trackers_description"
app:categoryItemTitle="@string/etp_redirect_trackers_title" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

@ -9,25 +9,11 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"> tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<ImageView
android:id="@+id/trackingProtectionCategoryIcon"
android:layout_width="@dimen/preference_icon_drawable_size"
android:layout_height="@dimen/preference_icon_drawable_size"
android:layout_marginStart="@dimen/library_item_icon_margin_horizontal"
android:layout_marginTop="@dimen/library_item_icon_margin_vertical"
android:layout_marginEnd="@dimen/library_item_icon_margin_horizontal"
android:layout_marginBottom="@dimen/library_item_icon_margin_vertical"
android:background="@drawable/ic_cryptominers"
android:clickable="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/trackingProtectionCategoryTitle" android:id="@+id/trackingProtectionCategoryTitle"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/radio_button_drawable_padding" android:layout_marginStart="@dimen/top_bar_alignment_margin_start"
android:layout_marginTop="@dimen/about_list_margin_top" android:layout_marginTop="@dimen/about_list_margin_top"
android:layout_marginEnd="@dimen/library_item_icon_margin_horizontal" android:layout_marginEnd="@dimen/library_item_icon_margin_horizontal"
android:clickable="false" android:clickable="false"
@ -36,15 +22,14 @@
app:layout_constraintBottom_toTopOf="@+id/trackingProtectionCategoryItemDescription" app:layout_constraintBottom_toTopOf="@+id/trackingProtectionCategoryItemDescription"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/trackingProtectionCategoryIcon" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent" />
tools:text="@tools:sample/lorem" />
<TextView <TextView
android:id="@+id/trackingProtectionCategoryItemDescription" android:id="@+id/trackingProtectionCategoryItemDescription"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/radio_button_drawable_padding" android:layout_marginStart="@dimen/top_bar_alignment_margin_start"
android:layout_marginEnd="@dimen/library_item_icon_margin_horizontal" android:layout_marginEnd="@dimen/library_item_icon_margin_horizontal"
android:layout_marginBottom="@dimen/tracking_protection_item_margin_bottom" android:layout_marginBottom="@dimen/tracking_protection_item_margin_bottom"
android:clickable="false" android:clickable="false"
@ -52,7 +37,6 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/trackingProtectionCategoryIcon" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/trackingProtectionCategoryTitle" app:layout_constraintTop_toBottomOf="@+id/trackingProtectionCategoryTitle" />
tools:text="@tools:sample/lorem/random" />
</merge> </merge>

@ -72,7 +72,6 @@
<declare-styleable name="TrackingProtectionCategory"> <declare-styleable name="TrackingProtectionCategory">
<attr name="categoryItemTitle" format="reference" /> <attr name="categoryItemTitle" format="reference" />
<attr name="categoryItemDescription" format="reference" /> <attr name="categoryItemDescription" format="reference" />
<attr name="categoryItemIcon" format="reference" />
</declare-styleable> </declare-styleable>
<declare-styleable name="SwitchWithDescription"> <declare-styleable name="SwitchWithDescription">

@ -1255,6 +1255,10 @@
<!-- Open source licenses page title <!-- Open source licenses page title
The first parameter is the app name --> The first parameter is the app name -->
<string name="open_source_licenses_title">%s | OSS Libraries</string> <string name="open_source_licenses_title">%s | OSS Libraries</string>
<!-- Category of trackers (redirect trackers) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_title">Redirect Trackers</string>
<!-- Description of redirect tracker cookies that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_description">Clears cookies set by redirects to known tracking websites.</string>
<!-- About page link text to open support link --> <!-- About page link text to open support link -->
<string name="about_support">Support</string> <string name="about_support">Support</string>

@ -3,7 +3,6 @@ package org.mozilla.fenix.components
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.mockkObject import io.mockk.mockkObject
import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy
import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertArrayEquals
@ -13,6 +12,7 @@ import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mozilla.fenix.Config import org.mozilla.fenix.Config
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.ReleaseChannel import org.mozilla.fenix.ReleaseChannel
import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.utils.Settings
@ -23,7 +23,7 @@ class TrackingProtectionPolicyFactoryTest {
@Test @Test
fun `WHEN useStrictMode is true then SHOULD return strict mode`() { fun `WHEN useStrictMode is true then SHOULD return strict mode`() {
val expected = EngineSession.TrackingProtectionPolicy.strict() val expected = TrackingProtectionPolicy.strict()
val factory = TrackingProtectionPolicyFactory(mockSettings(useStrict = true)) val factory = TrackingProtectionPolicyFactory(mockSettings(useStrict = true))
@ -35,12 +35,12 @@ class TrackingProtectionPolicyFactoryTest {
expected.assertPolicyEquals(privateOnly, checkPrivacy = false) expected.assertPolicyEquals(privateOnly, checkPrivacy = false)
expected.assertPolicyEquals(normalOnly, checkPrivacy = false) expected.assertPolicyEquals(normalOnly, checkPrivacy = false)
expected.assertPolicyEquals(always, checkPrivacy = false) expected.assertPolicyEquals(always, checkPrivacy = false)
EngineSession.TrackingProtectionPolicy.none().assertPolicyEquals(none, checkPrivacy = false) TrackingProtectionPolicy.none().assertPolicyEquals(none, checkPrivacy = false)
} }
@Test @Test
fun `WHEN neither use strict nor use custom is true SHOULD return recommended mode`() { fun `WHEN neither use strict nor use custom is true SHOULD return recommended mode`() {
val expected = EngineSession.TrackingProtectionPolicy.recommended() val expected = TrackingProtectionPolicy.recommended()
val factory = TrackingProtectionPolicyFactory(mockSettings(useStrict = false, useCustom = false)) val factory = TrackingProtectionPolicyFactory(mockSettings(useStrict = false, useCustom = false))
@ -52,13 +52,13 @@ class TrackingProtectionPolicyFactoryTest {
expected.assertPolicyEquals(privateOnly, checkPrivacy = false) expected.assertPolicyEquals(privateOnly, checkPrivacy = false)
expected.assertPolicyEquals(normalOnly, checkPrivacy = false) expected.assertPolicyEquals(normalOnly, checkPrivacy = false)
expected.assertPolicyEquals(always, checkPrivacy = false) expected.assertPolicyEquals(always, checkPrivacy = false)
EngineSession.TrackingProtectionPolicy.none().assertPolicyEquals(none, checkPrivacy = false) TrackingProtectionPolicy.none().assertPolicyEquals(none, checkPrivacy = false)
} }
@Test @Test
fun `GIVEN custom policy WHEN should not block cookies THEN tracking policy should not block cookies`() { fun `GIVEN custom policy WHEN should not block cookies THEN tracking policy should not block cookies`() {
val expected = EngineSession.TrackingProtectionPolicy.select( val expected = TrackingProtectionPolicy.select(
cookiePolicy = EngineSession.TrackingProtectionPolicy.CookiePolicy.ACCEPT_ALL, cookiePolicy = TrackingProtectionPolicy.CookiePolicy.ACCEPT_ALL,
trackingCategories = allTrackingCategories trackingCategories = allTrackingCategories
) )
@ -75,8 +75,8 @@ class TrackingProtectionPolicyFactoryTest {
@Test @Test
fun `GIVEN custom policy WHEN cookie policy block all THEN tracking policy should have cookie policy allow none`() { fun `GIVEN custom policy WHEN cookie policy block all THEN tracking policy should have cookie policy allow none`() {
val expected = EngineSession.TrackingProtectionPolicy.select( val expected = TrackingProtectionPolicy.select(
cookiePolicy = EngineSession.TrackingProtectionPolicy.CookiePolicy.ACCEPT_NONE, cookiePolicy = TrackingProtectionPolicy.CookiePolicy.ACCEPT_NONE,
trackingCategories = allTrackingCategories trackingCategories = allTrackingCategories
) )
@ -91,34 +91,6 @@ class TrackingProtectionPolicyFactoryTest {
expected.assertPolicyEquals(always, checkPrivacy = false) expected.assertPolicyEquals(always, checkPrivacy = false)
} }
@Test
fun `cookiePurging must be available ONLY in nightly or debug`() {
mockkObject(Config)
for (channel in ReleaseChannel.values()) {
every { Config.channel } returns channel
val shouldCookiePurgingActive = channel.isNightlyOrDebug
val customSetting =
settingsForCustom(shouldBlockCookiesInCustom = true, blockCookiesSelection = "all")
val stringSetting = mockSettings(useStrict = true)
val recommendedSetting = mockSettings(useTrackingProtection = true)
for (setting in arrayOf(recommendedSetting, stringSetting, customSetting)) {
val factory = TrackingProtectionPolicyFactory(setting)
val privateOnly =
factory.createTrackingProtectionPolicy(normalMode = false, privateMode = true)
val normalOnly =
factory.createTrackingProtectionPolicy(normalMode = true, privateMode = false)
val always =
factory.createTrackingProtectionPolicy(normalMode = true, privateMode = true)
assertEquals(shouldCookiePurgingActive, privateOnly.cookiePurging)
assertEquals(shouldCookiePurgingActive, normalOnly.cookiePurging)
assertEquals(shouldCookiePurgingActive, always.cookiePurging)
}
}
}
@Test @Test
fun `adaptPolicyToChannel MUST only update properties that have changed per given channel`() { fun `adaptPolicyToChannel MUST only update properties that have changed per given channel`() {
mockkObject(Config) mockkObject(Config)
@ -131,20 +103,17 @@ class TrackingProtectionPolicyFactoryTest {
for (channel in ReleaseChannel.values()) { for (channel in ReleaseChannel.values()) {
every { Config.channel } returns channel every { Config.channel } returns channel
val shouldCookiePurgingActive = channel.isNightlyOrDebug
for (policy in policies) { for (policy in policies) {
val adaptedPolicy = policy.adaptPolicyToChannel() val adaptedPolicy = policy.adaptPolicyToChannel()
policy.assertPolicyEquals(adaptedPolicy, checkPrivacy = false) policy.assertPolicyEquals(adaptedPolicy, checkPrivacy = false)
assertEquals(shouldCookiePurgingActive, adaptedPolicy.cookiePurging)
} }
} }
} }
@Test @Test
fun `GIVEN custom policy WHEN cookie policy social THEN tracking policy should have cookie policy allow non-trackers`() { fun `GIVEN custom policy WHEN cookie policy social THEN tracking policy should have cookie policy allow non-trackers`() {
val expected = EngineSession.TrackingProtectionPolicy.select( val expected = TrackingProtectionPolicy.select(
cookiePolicy = EngineSession.TrackingProtectionPolicy.CookiePolicy.ACCEPT_NON_TRACKERS, cookiePolicy = TrackingProtectionPolicy.CookiePolicy.ACCEPT_NON_TRACKERS,
trackingCategories = allTrackingCategories trackingCategories = allTrackingCategories
) )
@ -161,8 +130,8 @@ class TrackingProtectionPolicyFactoryTest {
@Test @Test
fun `GIVEN custom policy WHEN cookie policy accept visited THEN tracking policy should have cookie policy allow visited`() { fun `GIVEN custom policy WHEN cookie policy accept visited THEN tracking policy should have cookie policy allow visited`() {
val expected = EngineSession.TrackingProtectionPolicy.select( val expected = TrackingProtectionPolicy.select(
cookiePolicy = EngineSession.TrackingProtectionPolicy.CookiePolicy.ACCEPT_VISITED, cookiePolicy = TrackingProtectionPolicy.CookiePolicy.ACCEPT_VISITED,
trackingCategories = allTrackingCategories trackingCategories = allTrackingCategories
) )
@ -179,8 +148,8 @@ class TrackingProtectionPolicyFactoryTest {
@Test @Test
fun `GIVEN custom policy WHEN cookie policy block third party THEN tracking policy should have cookie policy allow first party`() { fun `GIVEN custom policy WHEN cookie policy block third party THEN tracking policy should have cookie policy allow first party`() {
val expected = EngineSession.TrackingProtectionPolicy.select( val expected = TrackingProtectionPolicy.select(
cookiePolicy = EngineSession.TrackingProtectionPolicy.CookiePolicy.ACCEPT_ONLY_FIRST_PARTY, cookiePolicy = TrackingProtectionPolicy.CookiePolicy.ACCEPT_ONLY_FIRST_PARTY,
trackingCategories = allTrackingCategories trackingCategories = allTrackingCategories
) )
@ -197,8 +166,8 @@ class TrackingProtectionPolicyFactoryTest {
@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 = EngineSession.TrackingProtectionPolicy.select( val expected = TrackingProtectionPolicy.select(
cookiePolicy = EngineSession.TrackingProtectionPolicy.CookiePolicy.ACCEPT_NONE, cookiePolicy = TrackingProtectionPolicy.CookiePolicy.ACCEPT_NONE,
trackingCategories = allTrackingCategories trackingCategories = allTrackingCategories
) )
@ -261,7 +230,7 @@ class TrackingProtectionPolicyFactoryTest {
useETPFactory = TrackingProtectionPolicyFactory(mockSettings(useTrackingProtection = false)) useETPFactory = TrackingProtectionPolicyFactory(mockSettings(useTrackingProtection = false))
policy = useETPFactory.createTrackingProtectionPolicy() policy = useETPFactory.createTrackingProtectionPolicy()
assertEquals(policy, EngineSession.TrackingProtectionPolicy.none()) assertEquals(policy, TrackingProtectionPolicy.none())
} }
@Test @Test
@ -306,14 +275,14 @@ class TrackingProtectionPolicyFactoryTest {
@Test @Test
fun `GIVEN custom policy WHEN default tracking policies THEN tracking policies should match default`() { fun `GIVEN custom policy WHEN default tracking policies THEN tracking policies should match default`() {
val defaultTrackingCategories = arrayOf( val defaultTrackingCategories = arrayOf(
EngineSession.TrackingProtectionPolicy.TrackingCategory.AD, TrackingProtectionPolicy.TrackingCategory.AD,
EngineSession.TrackingProtectionPolicy.TrackingCategory.ANALYTICS, TrackingProtectionPolicy.TrackingCategory.ANALYTICS,
EngineSession.TrackingProtectionPolicy.TrackingCategory.SOCIAL, TrackingProtectionPolicy.TrackingCategory.SOCIAL,
EngineSession.TrackingProtectionPolicy.TrackingCategory.MOZILLA_SOCIAL TrackingProtectionPolicy.TrackingCategory.MOZILLA_SOCIAL
) )
val expected = EngineSession.TrackingProtectionPolicy.select( val expected = TrackingProtectionPolicy.select(
cookiePolicy = EngineSession.TrackingProtectionPolicy.CookiePolicy.ACCEPT_NONE, cookiePolicy = TrackingProtectionPolicy.CookiePolicy.ACCEPT_NONE,
trackingCategories = defaultTrackingCategories trackingCategories = defaultTrackingCategories
) )
@ -332,8 +301,8 @@ class TrackingProtectionPolicyFactoryTest {
@Test @Test
fun `GIVEN custom policy WHEN all tracking policies THEN tracking policies should match all`() { fun `GIVEN custom policy WHEN all tracking policies THEN tracking policies should match all`() {
val expected = EngineSession.TrackingProtectionPolicy.select( val expected = TrackingProtectionPolicy.select(
cookiePolicy = EngineSession.TrackingProtectionPolicy.CookiePolicy.ACCEPT_NONE, cookiePolicy = TrackingProtectionPolicy.CookiePolicy.ACCEPT_NONE,
trackingCategories = allTrackingCategories trackingCategories = allTrackingCategories
) )
@ -353,15 +322,15 @@ class TrackingProtectionPolicyFactoryTest {
@Test @Test
fun `GIVEN custom policy WHEN some tracking policies THEN tracking policies should match passed policies`() { fun `GIVEN custom policy WHEN some tracking policies THEN tracking policies should match passed policies`() {
val someTrackingCategories = arrayOf( val someTrackingCategories = arrayOf(
EngineSession.TrackingProtectionPolicy.TrackingCategory.AD, TrackingProtectionPolicy.TrackingCategory.AD,
EngineSession.TrackingProtectionPolicy.TrackingCategory.ANALYTICS, TrackingProtectionPolicy.TrackingCategory.ANALYTICS,
EngineSession.TrackingProtectionPolicy.TrackingCategory.SOCIAL, TrackingProtectionPolicy.TrackingCategory.SOCIAL,
EngineSession.TrackingProtectionPolicy.TrackingCategory.MOZILLA_SOCIAL, TrackingProtectionPolicy.TrackingCategory.MOZILLA_SOCIAL,
EngineSession.TrackingProtectionPolicy.TrackingCategory.FINGERPRINTING TrackingProtectionPolicy.TrackingCategory.FINGERPRINTING
) )
val expected = EngineSession.TrackingProtectionPolicy.select( val expected = TrackingProtectionPolicy.select(
cookiePolicy = EngineSession.TrackingProtectionPolicy.CookiePolicy.ACCEPT_NONE, cookiePolicy = TrackingProtectionPolicy.CookiePolicy.ACCEPT_NONE,
trackingCategories = someTrackingCategories trackingCategories = someTrackingCategories
) )
@ -377,6 +346,55 @@ class TrackingProtectionPolicyFactoryTest {
expected.assertPolicyEquals(actual, checkPrivacy = false) expected.assertPolicyEquals(actual, checkPrivacy = false)
} }
@Test
fun `GIVEN custom policy WHEN some tracking policies THEN purge cookies`() {
val expected = TrackingProtectionPolicy.select(
cookiePolicy = TrackingProtectionPolicy.CookiePolicy.ACCEPT_NONE,
trackingCategories = allTrackingCategories,
cookiePurging = FeatureFlags.etpCookiePurging
)
val factory = TrackingProtectionPolicyFactory(settingsForCustom(shouldBlockCookiesInCustom = true))
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
fun `GIVEN strict policy WHEN some tracking policies THEN purge cookies`() {
val expected = TrackingProtectionPolicy.strict()
val factory = TrackingProtectionPolicyFactory(mockSettings(useStrict = true, useTrackingProtection = true))
val privateOnly = factory.createTrackingProtectionPolicy(normalMode = false, privateMode = true)
val normalOnly = factory.createTrackingProtectionPolicy(normalMode = true, privateMode = false)
val always = factory.createTrackingProtectionPolicy(normalMode = true, privateMode = true)
assertEquals(privateOnly.cookiePurging, expected.cookiePurging)
assertEquals(normalOnly.cookiePurging, expected.cookiePurging)
assertEquals(always.cookiePurging, expected.cookiePurging)
}
@Test
fun `GIVEN standard policy WHEN some tracking policies THEN purge cookies`() {
val expected = TrackingProtectionPolicy.recommended()
val factory = TrackingProtectionPolicyFactory(mockSettings(useStrict = false, useCustom = false, useTrackingProtection = true))
val privateOnly = factory.createTrackingProtectionPolicy(normalMode = false, privateMode = true)
val normalOnly = factory.createTrackingProtectionPolicy(normalMode = true, privateMode = false)
val always = factory.createTrackingProtectionPolicy(normalMode = true, privateMode = true)
assertEquals(privateOnly.cookiePurging, expected.cookiePurging)
assertEquals(normalOnly.cookiePurging, expected.cookiePurging)
assertEquals(always.cookiePurging, expected.cookiePurging)
}
} }
private fun mockSettings( private fun mockSettings(
@ -408,8 +426,8 @@ private fun settingsForCustom(
every { blockCryptominersInCustomTrackingProtection } returns blockCryptominers every { blockCryptominersInCustomTrackingProtection } returns blockCryptominers
} }
private fun EngineSession.TrackingProtectionPolicy.assertPolicyEquals( private fun TrackingProtectionPolicy.assertPolicyEquals(
actual: EngineSession.TrackingProtectionPolicy, actual: TrackingProtectionPolicy,
checkPrivacy: Boolean checkPrivacy: Boolean
) { ) {
assertEquals(this.cookiePolicy, actual.cookiePolicy) assertEquals(this.cookiePolicy, actual.cookiePolicy)
@ -426,16 +444,16 @@ private fun EngineSession.TrackingProtectionPolicy.assertPolicyEquals(
} }
} }
private fun Array<EngineSession.TrackingProtectionPolicy.TrackingCategory>.toInt(): Int { private fun Array<TrackingProtectionPolicy.TrackingCategory>.toInt(): Int {
return fold(initial = 0) { acc, next -> acc + next.id } return fold(initial = 0) { acc, next -> acc + next.id }
} }
private val allTrackingCategories = arrayOf( private val allTrackingCategories = arrayOf(
EngineSession.TrackingProtectionPolicy.TrackingCategory.AD, TrackingProtectionPolicy.TrackingCategory.AD,
EngineSession.TrackingProtectionPolicy.TrackingCategory.ANALYTICS, TrackingProtectionPolicy.TrackingCategory.ANALYTICS,
EngineSession.TrackingProtectionPolicy.TrackingCategory.SOCIAL, TrackingProtectionPolicy.TrackingCategory.SOCIAL,
EngineSession.TrackingProtectionPolicy.TrackingCategory.MOZILLA_SOCIAL, TrackingProtectionPolicy.TrackingCategory.MOZILLA_SOCIAL,
EngineSession.TrackingProtectionPolicy.TrackingCategory.SCRIPTS_AND_SUB_RESOURCES, TrackingProtectionPolicy.TrackingCategory.SCRIPTS_AND_SUB_RESOURCES,
EngineSession.TrackingProtectionPolicy.TrackingCategory.FINGERPRINTING, TrackingProtectionPolicy.TrackingCategory.FINGERPRINTING,
EngineSession.TrackingProtectionPolicy.TrackingCategory.CRYPTOMINING TrackingProtectionPolicy.TrackingCategory.CRYPTOMINING
) )

@ -19,6 +19,7 @@ import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mozilla.fenix.R import org.mozilla.fenix.R
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.SOCIAL_MEDIA_TRACKERS import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.SOCIAL_MEDIA_TRACKERS
@RunWith(FenixRobolectricTestRunner::class) @RunWith(FenixRobolectricTestRunner::class)
@ -97,4 +98,13 @@ class TrackingProtectionPanelViewTest {
view.social_media_trackers_loaded.performClick() view.social_media_trackers_loaded.performClick()
verify { interactor.openDetails(SOCIAL_MEDIA_TRACKERS, categoryBlocked = false) } verify { interactor.openDetails(SOCIAL_MEDIA_TRACKERS, categoryBlocked = false) }
} }
@Test
fun testCrossSiteTrackerClick() {
view.cross_site_tracking.performClick()
verify { interactor.openDetails(CROSS_SITE_TRACKING_COOKIES, categoryBlocked = true) }
view.cross_site_tracking_loaded.performClick()
verify { interactor.openDetails(CROSS_SITE_TRACKING_COOKIES, categoryBlocked = false) }
}
} }

Loading…
Cancel
Save