1
0
Fork 0

Tests and cleanup for tracking protection

master
Tiger Oakes 2020-06-01 08:55:43 -07:00 committed by Emily Kager
parent 9ef4d9bdae
commit 50441e28f1
12 changed files with 249 additions and 165 deletions

View File

@ -17,10 +17,11 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getPreferenceKey import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.trackingprotection.TrackingProtectionMode
/** /**
* Displays the toggle for tracking protection, options for tracking protection policy and a button * Displays the toggle for tracking protection, options for tracking protection policy and a button
@ -34,9 +35,6 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() {
requireView().findNavController().navigate(directions) requireView().findNavController().navigate(directions)
true true
} }
private lateinit var radioStrict: RadioButtonInfoPreference
private lateinit var radioStandard: RadioButtonInfoPreference
private lateinit var radioCustom: RadioButtonInfoPreference
private lateinit var customCookies: CheckBoxPreference private lateinit var customCookies: CheckBoxPreference
private lateinit var customCookiesSelect: DropDownPreference private lateinit var customCookiesSelect: DropDownPreference
private lateinit var customTracking: CheckBoxPreference private lateinit var customTracking: CheckBoxPreference
@ -46,10 +44,10 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.tracking_protection_preferences, rootKey) setPreferencesFromResource(R.xml.tracking_protection_preferences, rootKey)
bindStrict() val radioStrict = bindTrackingProtectionRadio(TrackingProtectionMode.STRICT)
bindStandard() val radioStandard = bindTrackingProtectionRadio(TrackingProtectionMode.STANDARD)
bindCustom() val radioCustom = bindCustom()
setupRadioGroups() setupRadioGroups(radioStrict, radioStandard, radioCustom)
updateCustomOptionsVisibility() updateCustomOptionsVisibility()
} }
@ -96,79 +94,42 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() {
preferenceExceptions?.onPreferenceClickListener = exceptionsClickListener preferenceExceptions?.onPreferenceClickListener = exceptionsClickListener
} }
private fun bindStrict() { private fun bindTrackingProtectionRadio(
val keyStrict = getString(R.string.pref_key_tracking_protection_strict_default) mode: TrackingProtectionMode
radioStrict = requireNotNull(findPreference(keyStrict)) ): RadioButtonInfoPreference {
radioStrict.contentDescription = val radio = requireNotNull(findPreference<RadioButtonInfoPreference>(
getString(R.string.preference_enhanced_tracking_protection_strict_info_button) getPreferenceKey(mode.preferenceKey)
))
radio.contentDescription = getString(mode.contentDescriptionRes)
radioStrict.onClickListener { val metrics = requireComponents.analytics.metrics
radio.onClickListener {
updateCustomOptionsVisibility() updateCustomOptionsVisibility()
updateTrackingProtectionPolicy() updateTrackingProtectionPolicy()
context?.metrics?.track( when (mode) {
Event.TrackingProtectionSettingChanged( TrackingProtectionMode.STANDARD ->
Event.TrackingProtectionSettingChanged.Setting.STRICT
)
)
}
radioStrict.onInfoClickListener {
nav(
R.id.trackingProtectionFragment,
TrackingProtectionFragmentDirections
.actionTrackingProtectionFragmentToTrackingProtectionBlockingFragment(
getString(R.string.preference_enhanced_tracking_protection_strict_default)
)
)
}
}
private fun bindStandard() {
val keyStandard = getString(R.string.pref_key_tracking_protection_standard_option)
radioStandard = requireNotNull(findPreference(keyStandard))
radioStandard.contentDescription =
getString(R.string.preference_enhanced_tracking_protection_standard_info_button)
radioStandard.onClickListener {
updateCustomOptionsVisibility()
updateTrackingProtectionPolicy()
context?.metrics?.track(
Event.TrackingProtectionSettingChanged(
Event.TrackingProtectionSettingChanged.Setting.STANDARD Event.TrackingProtectionSettingChanged.Setting.STANDARD
) TrackingProtectionMode.STRICT ->
) Event.TrackingProtectionSettingChanged.Setting.STRICT
TrackingProtectionMode.CUSTOM -> null
}?.let { setting ->
metrics.track(Event.TrackingProtectionSettingChanged(setting))
}
} }
radioStandard.onInfoClickListener { radio.onInfoClickListener {
nav( nav(
R.id.trackingProtectionFragment, R.id.trackingProtectionFragment,
TrackingProtectionFragmentDirections TrackingProtectionFragmentDirections
.actionTrackingProtectionFragmentToTrackingProtectionBlockingFragment( .actionTrackingProtectionFragmentToTrackingProtectionBlockingFragment(mode)
getString(R.string.preference_enhanced_tracking_protection_standard_option)
)
) )
} }
return radio
} }
private fun bindCustom() { private fun bindCustom(): RadioButtonInfoPreference {
val keyCustom = getString(R.string.pref_key_tracking_protection_custom_option) val radio = bindTrackingProtectionRadio(TrackingProtectionMode.CUSTOM)
radioCustom = requireNotNull(findPreference(keyCustom))
radioCustom.contentDescription =
getString(R.string.preference_enhanced_tracking_protection_custom_info_button)
radioCustom.onClickListener {
updateCustomOptionsVisibility()
updateTrackingProtectionPolicy()
}
radioCustom.onInfoClickListener {
nav(
R.id.trackingProtectionFragment,
TrackingProtectionFragmentDirections
.actionTrackingProtectionFragmentToTrackingProtectionBlockingFragment(
getString(R.string.preference_enhanced_tracking_protection_custom)
)
)
}
customCookies = requireNotNull( customCookies = requireNotNull(
findPreference( findPreference(
@ -254,6 +215,8 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() {
} }
updateCustomOptionsVisibility() updateCustomOptionsVisibility()
return radio
} }
private fun updateTrackingProtectionPolicy() { private fun updateTrackingProtectionPolicy() {
@ -265,7 +228,11 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() {
} }
} }
private fun setupRadioGroups() { private fun setupRadioGroups(
radioStrict: RadioButtonInfoPreference,
radioStandard: RadioButtonInfoPreference,
radioCustom: RadioButtonInfoPreference
) {
radioStandard.addToRadioGroup(radioStrict) radioStandard.addToRadioGroup(radioStrict)
radioStrict.addToRadioGroup(radioStandard) radioStrict.addToRadioGroup(radioStandard)

View File

@ -29,10 +29,7 @@ class SwitchWithDescription @JvmOverloads constructor(
R.drawable.ic_tracking_protection R.drawable.ic_tracking_protection
) )
switch_widget.putCompoundDrawablesRelativeWithIntrinsicBounds( switch_widget.putCompoundDrawablesRelativeWithIntrinsicBounds(
start = AppCompatResources.getDrawable( start = AppCompatResources.getDrawable(context, id)
context,
id
)
) )
trackingProtectionCategoryTitle.text = resources.getString( trackingProtectionCategoryTitle.text = resources.getString(
getResourceId( getResourceId(

View File

@ -53,7 +53,7 @@ class TrackerBuckets {
/** /**
* Gets the tracker URLs for a given category. * Gets the tracker URLs for a given category.
*/ */
operator fun get(key: TrackingProtectionCategory, blocked: Boolean) = fun get(key: TrackingProtectionCategory, blocked: Boolean) =
if (blocked) buckets.blockedBucketMap[key].orEmpty() else buckets.loadedBucketMap[key].orEmpty() if (blocked) buckets.blockedBucketMap[key].orEmpty() else buckets.loadedBucketMap[key].orEmpty()
companion object { companion object {

View File

@ -18,42 +18,33 @@ class TrackingProtectionBlockingFragment :
Fragment(R.layout.fragment_tracking_protection_blocking) { Fragment(R.layout.fragment_tracking_protection_blocking) {
private val args: TrackingProtectionBlockingFragmentArgs by navArgs() private val args: TrackingProtectionBlockingFragmentArgs by navArgs()
private var isCustomProtection: Boolean = false private val settings by lazy { requireContext().settings() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
isCustomProtection = requireContext().settings().useCustomTrackingProtection
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
when (args.protectionMode) { when (args.protectionMode) {
TrackingProtectionMode.STANDARD -> {
getString(R.string.preference_enhanced_tracking_protection_standard_option) -> {
category_tracking_content.isVisible = false category_tracking_content.isVisible = false
} }
getString(R.string.preference_enhanced_tracking_protection_strict) -> return TrackingProtectionMode.STRICT -> {}
getString(R.string.preference_enhanced_tracking_protection_custom) -> { TrackingProtectionMode.CUSTOM -> {
category_fingerprinters.isVisible = category_fingerprinters.isVisible =
requireContext().settings().blockFingerprintersInCustomTrackingProtection settings.blockFingerprintersInCustomTrackingProtection
category_cryptominers.isVisible = category_cryptominers.isVisible =
requireContext().settings().blockCryptominersInCustomTrackingProtection settings.blockCryptominersInCustomTrackingProtection
category_cookies.isVisible = category_cookies.isVisible =
requireContext().settings().blockCookiesInCustomTrackingProtection settings.blockCookiesInCustomTrackingProtection
category_tracking_content.isVisible = category_tracking_content.isVisible =
requireContext().settings().blockTrackingContentInCustomTrackingProtection settings.blockTrackingContentInCustomTrackingProtection
} }
else -> return
} }
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
showToolbar(args.protectionMode) showToolbar(getString(args.protectionMode.titleRes))
} }
} }

View File

@ -7,6 +7,7 @@ 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.*
@ -30,7 +31,7 @@ class TrackingProtectionCategoryItem @JvmOverloads constructor(
R.styleable.TrackingProtectionCategory_categoryItemIcon, R.styleable.TrackingProtectionCategory_categoryItemIcon,
R.drawable.ic_cryptominers R.drawable.ic_cryptominers
) )
trackingProtectionCategoryIcon?.background = resources.getDrawable(id, context.theme) trackingProtectionCategoryIcon?.background = AppCompatResources.getDrawable(context, id)
trackingProtectionCategoryTitle?.text = resources.getString( trackingProtectionCategoryTitle?.text = resources.getString(
getResourceId( getResourceId(
R.styleable.TrackingProtectionCategory_categoryItemTitle, R.styleable.TrackingProtectionCategory_categoryItemTitle,

View File

@ -0,0 +1,34 @@
/* 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.os.Parcelable
import androidx.annotation.StringRes
import kotlinx.android.parcel.Parcelize
import org.mozilla.fenix.R
@Parcelize
enum class TrackingProtectionMode(
@StringRes val preferenceKey: Int,
@StringRes val titleRes: Int,
@StringRes val contentDescriptionRes: Int
) : Parcelable {
STANDARD(
preferenceKey = R.string.pref_key_tracking_protection_standard_option,
titleRes = R.string.preference_enhanced_tracking_protection_standard_option,
contentDescriptionRes = R.string.preference_enhanced_tracking_protection_standard_info_button
),
STRICT(
preferenceKey = R.string.pref_key_tracking_protection_strict_default,
titleRes = R.string.preference_enhanced_tracking_protection_strict,
contentDescriptionRes = R.string.preference_enhanced_tracking_protection_strict_info_button
),
CUSTOM(
preferenceKey = R.string.pref_key_tracking_protection_custom_option,
titleRes = R.string.preference_enhanced_tracking_protection_custom,
contentDescriptionRes = R.string.preference_enhanced_tracking_protection_custom_info_button
)
}

View File

@ -57,6 +57,16 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), UserInt
private lateinit var trackingProtectionStore: TrackingProtectionStore private lateinit var trackingProtectionStore: TrackingProtectionStore
private lateinit var trackingProtectionView: TrackingProtectionPanelView private lateinit var trackingProtectionView: TrackingProtectionPanelView
private lateinit var trackingProtectionInteractor: TrackingProtectionPanelInteractor private lateinit var trackingProtectionInteractor: TrackingProtectionPanelInteractor
private lateinit var trackingProtectionUseCases: TrackingProtectionUseCases
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val components = requireComponents
trackingProtectionUseCases = TrackingProtectionUseCases(
sessionManager = components.core.sessionManager,
engine = components.core.engine
)
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@ -85,47 +95,34 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), UserInt
) )
trackingProtectionView = trackingProtectionView =
TrackingProtectionPanelView(view.fragment_tp, trackingProtectionInteractor) TrackingProtectionPanelView(view.fragment_tp, trackingProtectionInteractor)
updateTrackers() session?.let { updateTrackers(it) }
return view return view
} }
private val sessionObserver = object : Session.Observer { private val sessionObserver = object : Session.Observer {
override fun onUrlChanged(session: Session, url: String) { override fun onUrlChanged(session: Session, url: String) {
trackingProtectionStore.dispatch( trackingProtectionStore.dispatch(TrackingProtectionAction.UrlChange(url))
TrackingProtectionAction.UrlChange(url)
)
} }
override fun onTrackerBlocked(session: Session, tracker: Tracker, all: List<Tracker>) { override fun onTrackerBlocked(session: Session, tracker: Tracker, all: List<Tracker>) {
updateTrackers() updateTrackers(session)
} }
override fun onTrackerLoaded(session: Session, tracker: Tracker, all: List<Tracker>) { override fun onTrackerLoaded(session: Session, tracker: Tracker, all: List<Tracker>) {
updateTrackers() updateTrackers(session)
} }
} }
private fun updateTrackers() { private fun updateTrackers(session: Session) {
context?.let { context -> trackingProtectionUseCases.fetchTrackingLogs(
val session = session,
context.components.core.sessionManager.findSessionById(args.sessionId) ?: return onSuccess = {
val useCase = TrackingProtectionUseCases( trackingProtectionStore.dispatch(TrackingProtectionAction.TrackerLogChange(it))
sessionManager = context.components.core.sessionManager, },
engine = context.components.core.engine onError = {
) Logger.error("TrackingProtectionUseCases - fetchTrackingLogs onError", it)
}
useCase.fetchTrackingLogs( )
session,
onSuccess = {
trackingProtectionStore.dispatch(
TrackingProtectionAction.TrackerLogChange(it)
)
},
onError = {
Logger.error("TrackingProtectionUseCases - fetchTrackingLogs onError", it)
}
)
}
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -150,17 +147,13 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), UserInt
private fun toggleTrackingProtection(isEnabled: Boolean) { private fun toggleTrackingProtection(isEnabled: Boolean) {
context?.let { context -> context?.let { context ->
val useCase = TrackingProtectionUseCases(
sessionManager = context.components.core.sessionManager,
engine = context.components.core.engine
)
val session = context.components.core.sessionManager.findSessionById(args.sessionId) val session = context.components.core.sessionManager.findSessionById(args.sessionId)
session?.let { session?.let {
if (isEnabled) { if (isEnabled) {
useCase.removeException(it) trackingProtectionUseCases.removeException(it)
} else { } else {
context.metrics.track(Event.TrackingProtectionException) context.metrics.track(Event.TrackingProtectionException)
useCase.addException(it) trackingProtectionUseCases.addException(it)
} }
with(context.components) { with(context.components) {

View File

@ -77,11 +77,18 @@ class TrackingProtectionPanelView(
private var shouldFocusAccessibilityView: Boolean = true private var shouldFocusAccessibilityView: Boolean = true
fun update(state: TrackingProtectionState) { init {
if (state.mode != mode) { protection_settings.setOnClickListener {
mode = state.mode interactor.selectTrackingProtectionSettings()
} }
details_back.setOnClickListener {
interactor.onBackPressed()
}
setCategoryClickListeners()
}
fun update(state: TrackingProtectionState) {
mode = state.mode
bucketedTrackers.updateIfNeeded(state.listTrackers) bucketedTrackers.updateIfNeeded(state.listTrackers)
when (val mode = state.mode) { when (val mode = state.mode) {
@ -103,16 +110,31 @@ class TrackingProtectionPanelView(
not_blocking_header.isGone = bucketedTrackers.loadedIsEmpty() not_blocking_header.isGone = bucketedTrackers.loadedIsEmpty()
bindUrl(state.url) bindUrl(state.url)
bindTrackingProtectionInfo(state.isTrackingProtectionEnabled) bindTrackingProtectionInfo(state.isTrackingProtectionEnabled)
protection_settings.setOnClickListener {
interactor.selectTrackingProtectionSettings()
}
blocking_header.isGone = bucketedTrackers.blockedIsEmpty() blocking_header.isGone = bucketedTrackers.blockedIsEmpty()
updateCategoryVisibility() updateCategoryVisibility()
setCategoryClickListeners()
focusAccessibilityLastUsedCategory(state.lastAccessedCategory) focusAccessibilityLastUsedCategory(state.lastAccessedCategory)
} }
private fun setUIForDetailsMode(
category: TrackingProtectionCategory,
categoryBlocked: Boolean
) {
normal_mode.visibility = View.GONE
details_mode.visibility = View.VISIBLE
category_title.setText(category.title)
blocking_text_list.text = bucketedTrackers.get(category, categoryBlocked).joinToString("\n")
category_description.setText(category.description)
details_blocking_header.setText(if (categoryBlocked) {
R.string.enhanced_tracking_protection_blocked
} else {
R.string.enhanced_tracking_protection_allowed
})
details_back.requestFocus()
details_back.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)
}
/** /**
* Will force accessibility focus to last entered details category. * Will force accessibility focus to last entered details category.
* Called when user returns from details_mode. * Called when user returns from details_mode.
@ -180,32 +202,6 @@ class TrackingProtectionPanelView(
interactor.openDetails(category, categoryBlocked = !isLoaded(v)) interactor.openDetails(category, categoryBlocked = !isLoaded(v))
} }
private fun setUIForDetailsMode(
category: TrackingProtectionCategory,
categoryBlocked: Boolean
) {
val context = view.context
normal_mode.visibility = View.GONE
details_mode.visibility = View.VISIBLE
category_title.text = context.getString(category.title)
blocking_text_list.text = bucketedTrackers.get(category, categoryBlocked).joinToString("\n")
category_description.text = context.getString(category.description)
details_blocking_header.text = context.getString(
if (categoryBlocked) {
R.string.enhanced_tracking_protection_blocked
} else {
R.string.enhanced_tracking_protection_allowed
}
)
details_back.setOnClickListener {
interactor.onBackPressed()
}
details_back.requestFocus()
details_back.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)
}
private fun bindUrl(url: String) { private fun bindUrl(url: String) {
this.url.text = url.toUri().hostWithoutCommonPrefixes this.url.text = url.toUri().hostWithoutCommonPrefixes
} }
@ -239,9 +235,9 @@ class TrackingProtectionPanelView(
ViewCompat.setAccessibilityDelegate(view2, object : AccessibilityDelegateCompat() { ViewCompat.setAccessibilityDelegate(view2, object : AccessibilityDelegateCompat() {
override fun onInitializeAccessibilityNodeInfo( override fun onInitializeAccessibilityNodeInfo(
host: View?, host: View?,
info: AccessibilityNodeInfoCompat? info: AccessibilityNodeInfoCompat
) { ) {
info?.setTraversalAfter(view1) info.setTraversalAfter(view1)
super.onInitializeAccessibilityNodeInfo(host, info) super.onInitializeAccessibilityNodeInfo(host, info)
} }
}) })

View File

@ -4,6 +4,7 @@
package org.mozilla.fenix.trackingprotection package org.mozilla.fenix.trackingprotection
import androidx.annotation.StringRes
import mozilla.components.browser.session.Session import mozilla.components.browser.session.Session
import mozilla.components.concept.engine.content.blocking.TrackerLog import mozilla.components.concept.engine.content.blocking.TrackerLog
import mozilla.components.lib.state.Action import mozilla.components.lib.state.Action
@ -73,7 +74,10 @@ data class TrackingProtectionState(
/** /**
* The 5 categories of Tracking Protection to display * The 5 categories of Tracking Protection to display
*/ */
enum class TrackingProtectionCategory(val title: Int, val description: Int) { enum class TrackingProtectionCategory(
@StringRes val title: Int,
@StringRes val description: Int
) {
SOCIAL_MEDIA_TRACKERS( SOCIAL_MEDIA_TRACKERS(
R.string.etp_social_media_trackers_title, R.string.etp_social_media_trackers_title,
R.string.etp_social_media_trackers_description R.string.etp_social_media_trackers_description

View File

@ -188,7 +188,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="20dp" android:layout_marginStart="20dp"
android:tint="?attr/primaryText" app:tint="?attr/primaryText"
android:contentDescription="@string/etp_back_button_content_description" android:contentDescription="@string/etp_back_button_content_description"
app:layout_constraintBottom_toBottomOf="@+id/category_description" app:layout_constraintBottom_toBottomOf="@+id/category_description"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View File

@ -696,10 +696,11 @@
</dialog> </dialog>
<fragment <fragment
android:id="@+id/trackingProtectionBlockingFragment" android:id="@+id/trackingProtectionBlockingFragment"
android:name="org.mozilla.fenix.trackingprotection.TrackingProtectionBlockingFragment"> android:name="org.mozilla.fenix.trackingprotection.TrackingProtectionBlockingFragment"
tools:layout="@layout/fragment_tracking_protection_blocking">
<argument <argument
android:name="protectionMode" android:name="protectionMode"
app:argType="string" /> app:argType="org.mozilla.fenix.trackingprotection.TrackingProtectionMode" />
</fragment> </fragment>
<fragment <fragment
android:id="@+id/deleteBrowsingDataOnQuitFragment" android:id="@+id/deleteBrowsingDataOnQuitFragment"

View File

@ -0,0 +1,100 @@
/* 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.view.ViewGroup
import android.widget.FrameLayout
import androidx.core.view.isVisible
import io.mockk.mockk
import io.mockk.verify
import kotlinx.android.synthetic.main.component_tracking_protection_panel.*
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.SOCIAL_MEDIA_TRACKERS
@RunWith(FenixRobolectricTestRunner::class)
class TrackingProtectionPanelViewTest {
private lateinit var container: ViewGroup
private lateinit var interactor: TrackingProtectionPanelInteractor
private lateinit var view: TrackingProtectionPanelView
private val baseState = TrackingProtectionState(
session = null,
url = "",
isTrackingProtectionEnabled = false,
listTrackers = emptyList(),
mode = TrackingProtectionState.Mode.Normal,
lastAccessedCategory = ""
)
@Before
fun setup() {
container = FrameLayout(testContext)
interactor = mockk(relaxUnitFun = true)
view = TrackingProtectionPanelView(container, interactor)
}
@Test
fun testNormalModeUi() {
view.update(baseState.copy(mode = TrackingProtectionState.Mode.Normal))
assertFalse(view.details_mode.isVisible)
assertTrue(view.normal_mode.isVisible)
assertTrue(view.protection_settings.isVisible)
assertFalse(view.not_blocking_header.isVisible)
assertFalse(view.blocking_header.isVisible)
}
@Test
fun testPrivateModeUi() {
view.update(baseState.copy(
mode = TrackingProtectionState.Mode.Details(
selectedCategory = TrackingProtectionCategory.TRACKING_CONTENT,
categoryBlocked = false
)
))
assertTrue(view.details_mode.isVisible)
assertFalse(view.normal_mode.isVisible)
assertEquals(
testContext.getString(R.string.etp_tracking_content_title),
view.category_title.text
)
assertEquals(
testContext.getString(R.string.etp_tracking_content_description),
view.category_description.text
)
assertEquals(
testContext.getString(R.string.enhanced_tracking_protection_allowed),
view.details_blocking_header.text
)
}
@Test
fun testProtectionSettings() {
view.protection_settings.performClick()
verify { interactor.selectTrackingProtectionSettings() }
}
@Test
fun testDetailsBack() {
view.details_back.performClick()
verify { interactor.onBackPressed() }
}
@Test
fun testSocialMediaTrackerClick() {
view.social_media_trackers.performClick()
verify { interactor.openDetails(SOCIAL_MEDIA_TRACKERS, categoryBlocked = true) }
view.social_media_trackers_loaded.performClick()
verify { interactor.openDetails(SOCIAL_MEDIA_TRACKERS, categoryBlocked = false) }
}
}