1
0
Fork 0

Use new API for ETP Exceptions

master
ekager 2019-10-01 21:45:04 -07:00 committed by Emily Kager
parent ca8ba57635
commit 18c0525ff6
15 changed files with 170 additions and 216 deletions

View File

@ -1378,7 +1378,7 @@ tracking_protection:
etp_setting_changed:
type: event
description: >
A user added a tracking protection exception through the TP toggle in the panel.
A user changed their tracking protection level setting to either strict or standard.
extra_keys:
etp_setting:
description: "The new setting for ETP: strict, standard"

View File

@ -11,17 +11,15 @@ import mozilla.components.browser.errorpages.ErrorType
import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.engine.request.RequestInterceptor
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.exceptions.ExceptionDomains
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.tryGetHostFromUrl
class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? {
val host = uri.tryGetHostFromUrl()
adjustTrackingProtection(host, context, session)
override fun onLoadRequest(
session: EngineSession,
uri: String
): RequestInterceptor.InterceptionResponse? {
adjustTrackingProtection(context, session)
// WebChannel-driven authentication does not require a separate redirect interceptor.
return if (context.isInExperiment(Experiments.asFeatureWebChannelsDisabled)) {
context.components.services.accountsAuthFeature.interceptor.onLoadRequest(session, uri)
@ -30,10 +28,9 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
}
}
private fun adjustTrackingProtection(host: String, context: Context, session: EngineSession) {
val trackingProtectionException = ExceptionDomains(context).load().contains(host)
private fun adjustTrackingProtection(context: Context, session: EngineSession) {
val trackingProtectionEnabled = context.settings().shouldUseTrackingProtection
if (trackingProtectionException || !trackingProtectionEnabled) {
if (!trackingProtectionEnabled) {
session.disableTrackingProtection()
} else {
val core = context.components.core

View File

@ -36,6 +36,7 @@ import mozilla.appservices.places.BookmarkRoot
import mozilla.components.browser.session.Session
import mozilla.components.feature.contextmenu.ContextMenuCandidate
import mozilla.components.feature.readerview.ReaderViewFeature
import mozilla.components.feature.session.TrackingProtectionUseCases
import mozilla.components.feature.sitepermissions.SitePermissions
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.support.base.feature.BackHandler
@ -224,14 +225,21 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
}
override fun navToTrackingProtectionPanel(session: Session) {
val directions =
BrowserFragmentDirections.actionBrowserFragmentToTrackingProtectionPanelDialogFragment(
sessionId = session.id,
url = session.url,
trackingProtectionEnabled = session.trackerBlockingEnabled,
gravity = getAppropriateLayoutGravity()
)
nav(R.id.browserFragment, directions)
val useCase = TrackingProtectionUseCases(
sessionManager = requireComponents.core.sessionManager,
engine = requireComponents.core.engine
)
useCase.containsException(session) { contains ->
val isEnabled = session.trackerBlockingEnabled && !contains
val directions =
BrowserFragmentDirections.actionBrowserFragmentToTrackingProtectionPanelDialogFragment(
sessionId = session.id,
url = session.url,
trackingProtectionEnabled = isEnabled,
gravity = getAppropriateLayoutGravity()
)
nav(R.id.browserFragment, directions)
}
}
override fun getEngineMargins(): Pair<Int, Int> {

View File

@ -21,6 +21,7 @@ import mozilla.components.feature.pwa.ext.trustedOrigins
import mozilla.components.feature.pwa.feature.WebAppActivityFeature
import mozilla.components.feature.pwa.feature.WebAppHideToolbarFeature
import mozilla.components.feature.pwa.feature.WebAppSiteControlsFeature
import mozilla.components.feature.session.TrackingProtectionUseCases
import mozilla.components.feature.sitepermissions.SitePermissions
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.support.base.feature.BackHandler
@ -154,15 +155,22 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), BackHandler {
}
override fun navToTrackingProtectionPanel(session: Session) {
val directions =
ExternalAppBrowserFragmentDirections
.actionExternalAppBrowserFragmentToTrackingProtectionPanelDialogFragment(
sessionId = session.id,
url = session.url,
trackingProtectionEnabled = session.trackerBlockingEnabled,
gravity = getAppropriateLayoutGravity()
)
nav(R.id.externalAppBrowserFragment, directions)
val useCase = TrackingProtectionUseCases(
sessionManager = requireComponents.core.sessionManager,
engine = requireComponents.core.engine
)
useCase.containsException(session) { contains ->
val isEnabled = session.trackerBlockingEnabled && !contains
val directions =
ExternalAppBrowserFragmentDirections
.actionExternalAppBrowserFragmentToTrackingProtectionPanelDialogFragment(
sessionId = session.id,
url = session.url,
trackingProtectionEnabled = isEnabled,
gravity = getAppropriateLayoutGravity()
)
nav(R.id.externalAppBrowserFragment, directions)
}
}
override fun getEngineMargins(): Pair<Int, Int> {

View File

@ -1,87 +0,0 @@
/* 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.exceptions
import android.content.Context
import android.content.SharedPreferences
import mozilla.components.support.ktx.android.content.PreferencesHolder
import mozilla.components.support.ktx.android.content.stringPreference
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.metrics
/**
* Contains functionality to manage custom domains for allow-list.
*/
class ExceptionDomains(val context: Context) : PreferencesHolder {
override val preferences: SharedPreferences =
context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE)
private var domains by stringPreference(KEY_DOMAINS, default = "")
/**
* Loads the previously added/saved custom domains from preferences.
*
* @return list of custom domains
*/
fun load(): List<String> {
if (exceptions == null) {
exceptions = domains.split(SEPARATOR).filter { it.isNotEmpty() }
}
return exceptions.orEmpty()
}
/**
* Saves the provided domains to preferences.
*
* @param domains list of domains
*/
fun save(domains: List<String>) {
exceptions = domains
this.domains = domains.joinToString(separator = SEPARATOR)
}
/**
* Adds the provided domain to preferences.
*
* @param domain the domain to add
*/
fun add(domain: String) {
save(domains = load() + domain)
}
/**
* Removes the provided domain from preferences.
*
* @param domains the domain to remove
*/
fun remove(domains: List<String>) {
save(domains = load() - domains)
}
/**
* Adds or removes the provided domain from preferences.
*
* If present, the domain will be removed. Otherwise, it will be added.
*/
fun toggle(domain: String) {
if (domain in load()) {
remove(listOf(domain))
} else {
context.metrics.track(Event.TrackingProtectionException)
add(domain)
}
}
companion object {
private const val PREFERENCE_NAME = "exceptions"
private const val KEY_DOMAINS = "exceptions_domains"
private const val SEPARATOR = "@<;>@"
private var exceptions: List<String>? = null
}
}

View File

@ -5,29 +5,28 @@
package org.mozilla.fenix.exceptions
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import kotlinx.android.synthetic.main.fragment_exceptions.view.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import mozilla.components.feature.session.TrackingProtectionUseCases
import mozilla.components.lib.state.ext.consumeFrom
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.settings.SupportUtils
class ExceptionsFragment : Fragment() {
private lateinit var exceptionsStore: ExceptionsFragmentStore
private lateinit var exceptionsView: ExceptionsView
private lateinit var exceptionsInteractor: ExceptionsInteractor
private lateinit var trackingProtectionUseCases: TrackingProtectionUseCases
override fun onResume() {
super.onResume()
@ -41,16 +40,21 @@ class ExceptionsFragment : Fragment() {
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_exceptions, container, false)
trackingProtectionUseCases = TrackingProtectionUseCases(
sessionManager = view.context.components.core.sessionManager,
engine = view.context.components.core.engine
)
exceptionsStore = StoreProvider.get(this) {
ExceptionsFragmentStore(
ExceptionsFragmentState(
items = loadAndMapExceptions()
items = listOf()
)
)
}
exceptionsInteractor =
ExceptionsInteractor(::openLearnMore, ::deleteOneItem, ::deleteAllItems)
exceptionsView = ExceptionsView(view.exceptionsLayout, exceptionsInteractor)
reloadExceptions()
return view
}
@ -63,20 +67,15 @@ class ExceptionsFragment : Fragment() {
}
private fun deleteAllItems() {
viewLifecycleOwner.lifecycleScope.launch(IO) {
ExceptionDomains(requireContext()).run {
val domains = load()
remove(domains)
}
reloadData()
}
trackingProtectionUseCases.removeAllExceptions()
reloadExceptions()
}
private fun deleteOneItem(item: ExceptionsItem) {
viewLifecycleOwner.lifecycleScope.launch(IO) {
ExceptionDomains(requireContext()).remove(listOf(item.url))
reloadData()
}
// We can't currently delete one item in this Exceptions list with a URL with the GV API
// See https://github.com/mozilla-mobile/android-components/issues/4699
Log.e("Remove one exception", "$item")
reloadExceptions()
}
private fun openLearnMore() {
@ -88,18 +87,13 @@ class ExceptionsFragment : Fragment() {
)
}
private fun loadAndMapExceptions(): List<ExceptionsItem> {
return ExceptionDomains(requireContext()).load()
.map { item -> ExceptionsItem(item) }
}
private suspend fun reloadData() {
val items = loadAndMapExceptions()
coroutineScope {
launch(Main) {
exceptionsStore.dispatch(ExceptionsFragmentAction.Change(items))
}
private fun reloadExceptions() {
trackingProtectionUseCases.fetchExceptions { resultList ->
exceptionsStore.dispatch(ExceptionsFragmentAction.Change(resultList.map {
ExceptionsItem(
it
)
}))
}
}
}

View File

@ -14,13 +14,14 @@ import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.launch
import mozilla.components.browser.session.Session
import mozilla.components.feature.session.SessionUseCases.ReloadUrlUseCase
import mozilla.components.feature.session.TrackingProtectionUseCases
import mozilla.components.feature.sitepermissions.SitePermissions
import mozilla.components.feature.tabs.TabsUseCases.AddNewTabUseCase
import mozilla.components.support.base.feature.OnNeedToRequestPermissions
import org.mozilla.fenix.browser.BrowserFragment
import org.mozilla.fenix.components.PermissionStorage
import org.mozilla.fenix.exceptions.ExceptionDomains
import org.mozilla.fenix.ext.tryGetHostFromUrl
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.settings.PhoneFeature
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeEnabled
import org.mozilla.fenix.settings.toggle
@ -36,9 +37,8 @@ interface QuickSettingsController {
/**
* Handles turning on/off tracking protection.
*
* @param websiteUrl [String] the website URL for which to toggle tracking protection.
*/
fun handleTrackingProtectionToggled(websiteUrl: String, trackingEnabled: Boolean)
* */
fun handleTrackingProtectionToggled(trackingEnabled: Boolean)
/**
* Handles showing the tracking protection settings.
@ -89,7 +89,6 @@ interface QuickSettingsController {
* @param sitePermissions [SitePermissions]? list of website permissions and their status.
* @param settings [Settings] application settings.
* @param permissionStorage [PermissionStorage] app state for website permissions exception.
* @param trackingExceptions [ExceptionDomains] allows setting whether to allow trackers or not.
* @param reload [ReloadUrlUseCase] callback allowing for reloading the current web page.
* @param addNewTab [AddNewTabUseCase] callback allowing for loading a URL in a new tab.
* @param requestRuntimePermissions [OnNeedToRequestPermissions] callback allowing for requesting
@ -98,6 +97,7 @@ interface QuickSettingsController {
* @param displayTrackingProtection callback for when the [TrackingProtectionView] needs to be displayed.
* @param displayPermissions callback for when [WebsitePermissionsView] needs to be displayed.
* @param dismiss callback allowing to request this entire Fragment to be dismissed.
* @param trackingProtectionUseCases usecase allowing us to add or remove tracking protection exceptions
*/
@Suppress("TooManyFunctions")
class DefaultQuickSettingsController(
@ -109,22 +109,28 @@ class DefaultQuickSettingsController(
private var sitePermissions: SitePermissions?,
private val settings: Settings,
private val permissionStorage: PermissionStorage,
private val trackingExceptions: ExceptionDomains,
private val reload: ReloadUrlUseCase,
private val addNewTab: AddNewTabUseCase,
private val requestRuntimePermissions: OnNeedToRequestPermissions = { },
private val reportSiteIssue: () -> Unit,
private val displayTrackingProtection: () -> Unit,
private val displayPermissions: () -> Unit,
private val dismiss: () -> Unit
private val dismiss: () -> Unit,
private val trackingProtectionUseCases: TrackingProtectionUseCases
) : QuickSettingsController {
override fun handleTrackingProtectionToggled(
websiteUrl: String,
trackingEnabled: Boolean
) {
val host = websiteUrl.tryGetHostFromUrl()
trackingExceptions.toggle(host)
session?.let {
if (trackingEnabled) {
trackingProtectionUseCases.removeException(it)
} else {
context.metrics.track(Event.TrackingProtectionException)
trackingProtectionUseCases.addException(it)
}
}
reload(session)
quickSettingsStore.dispatch(
@ -246,13 +252,17 @@ class DefaultQuickSettingsController(
return when (this) {
PhoneFeature.CAMERA -> WebsitePermission.Camera(
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid)
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid
)
PhoneFeature.LOCATION -> WebsitePermission.Location(
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid)
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid
)
PhoneFeature.MICROPHONE -> WebsitePermission.Microphone(
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid)
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid
)
PhoneFeature.NOTIFICATION -> WebsitePermission.Notification(
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid)
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid
)
PhoneFeature.AUTOPLAY -> defaultWebsitePermission!! // fail-fast
}
}

View File

@ -21,8 +21,8 @@ class QuickSettingsInteractor(
controller.handleReportTrackingProblem(websiteUrl)
}
override fun onProtectionToggled(websiteUrl: String, trackingEnabled: Boolean) {
controller.handleTrackingProtectionToggled(websiteUrl, trackingEnabled)
override fun onProtectionToggled(trackingEnabled: Boolean) {
controller.handleTrackingProtectionToggled(trackingEnabled)
}
override fun onProtectionSettingsSelected() {

View File

@ -26,11 +26,11 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.android.synthetic.main.fragment_quick_settings_dialog_sheet.*
import kotlinx.android.synthetic.main.fragment_quick_settings_dialog_sheet.view.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import mozilla.components.feature.session.TrackingProtectionUseCases
import mozilla.components.lib.state.ext.consumeFrom
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.IntentReceiverActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.exceptions.ExceptionDomains
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.settings.PhoneFeature
import org.mozilla.fenix.utils.Settings
@ -50,7 +50,11 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() {
private lateinit var websiteTrackingProtectionView: TrackingProtectionView
private lateinit var interactor: QuickSettingsInteractor
private val safeArguments get() = requireNotNull(arguments)
private val promptGravity: Int by lazy { QuickSettingsSheetDialogFragmentArgs.fromBundle(safeArguments).gravity }
private val promptGravity: Int by lazy {
QuickSettingsSheetDialogFragmentArgs.fromBundle(
safeArguments
).gravity
}
override fun onCreateView(
inflater: LayoutInflater,
@ -80,7 +84,6 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() {
sitePermissions = args.sitePermissions,
settings = Settings.getInstance(context),
permissionStorage = context.components.core.permissionStorage,
trackingExceptions = ExceptionDomains(context),
reload = context.components.useCases.sessionUseCases.reload,
addNewTab = context.components.useCases.tabsUseCases.addTab,
requestRuntimePermissions = { permissions ->
@ -89,13 +92,20 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() {
reportSiteIssue = ::launchIntentReceiver,
displayTrackingProtection = ::showTrackingProtectionView,
displayPermissions = ::showPermissionsView,
dismiss = ::dismiss
dismiss = ::dismiss,
trackingProtectionUseCases = TrackingProtectionUseCases(
context.components.core.sessionManager,
context.components.core.engine
)
)
interactor = QuickSettingsInteractor(quickSettingsController)
websiteTrackingProtectionView = TrackingProtectionView(rootView.trackingProtectionLayout, interactor)
websiteTrackingProtectionView =
TrackingProtectionView(rootView.trackingProtectionLayout, interactor)
websiteInfoView = WebsiteInfoView(rootView.websiteInfoLayout)
websitePermissionsView = WebsitePermissionsView(rootView.websitePermissionsLayout, interactor)
websitePermissionsView =
WebsitePermissionsView(rootView.websitePermissionsLayout, interactor)
return rootView
}

View File

@ -26,7 +26,7 @@ interface TrackingProtectionInteractor {
/**
* Indicates the user want to toggle the tracking protection on / off.
*/
fun onProtectionToggled(websiteUrl: String, trackingEnabled: Boolean)
fun onProtectionToggled(trackingEnabled: Boolean)
/**
* Indicates the user want to see all tracking protection settings.
@ -84,7 +84,7 @@ class TrackingProtectionView(
trackingProtectionSwitch.isEnabled = state.isTrackingProtectionEnabledPerApp
if (state.isTrackingProtectionEnabledPerApp) {
trackingProtectionSwitch.setOnCheckedChangeListener { _, isChecked ->
interactor.onProtectionToggled(state.websiteUrl, isChecked)
interactor.onProtectionToggled(isChecked)
}
}
}

View File

@ -32,12 +32,10 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.exceptions.ExceptionDomains
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.tryGetHostFromUrl
class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), BackHandler {
@ -172,12 +170,22 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), BackHan
private fun toggleTrackingProtection(isEnabled: Boolean) {
context?.let { context ->
val host = url.tryGetHostFromUrl()
lifecycleScope.launch {
ExceptionDomains(context).toggle(host)
}
with(context.components) {
useCases.sessionUseCases.reload.invoke(core.sessionManager.findSessionById(sessionId))
val useCase = TrackingProtectionUseCases(
sessionManager = context.components.core.sessionManager,
engine = context.components.core.engine
)
val session = context.components.core.sessionManager.findSessionById(sessionId)
session?.let {
if (isEnabled) {
useCase.removeException(it)
} else {
context.metrics.track(Event.TrackingProtectionException)
useCase.addException(it)
}
with(context.components) {
useCases.sessionUseCases.reload.invoke(session)
}
}
}
trackingProtectionStore.dispatch(TrackingProtectionAction.TrackerBlockingChanged(isEnabled))

View File

@ -47,6 +47,7 @@
tools:text="mozilla.org" />
<ImageButton
android:visibility="gone"
android:id="@+id/delete_exception"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -24,6 +24,7 @@ import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.runBlocking
import mozilla.components.browser.session.Session
import mozilla.components.feature.session.SessionUseCases
import mozilla.components.feature.session.TrackingProtectionUseCases
import mozilla.components.feature.sitepermissions.SitePermissions
import mozilla.components.feature.sitepermissions.SitePermissions.Status.NO_DECISION
import mozilla.components.feature.tabs.TabsUseCases
@ -33,7 +34,8 @@ import org.junit.runner.RunWith
import org.mozilla.fenix.TestApplication
import org.mozilla.fenix.browser.BrowserFragment
import org.mozilla.fenix.components.PermissionStorage
import org.mozilla.fenix.exceptions.ExceptionDomains
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.settings.PhoneFeature
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeEnabled
import org.mozilla.fenix.settings.toggle
@ -53,7 +55,6 @@ class DefaultQuickSettingsControllerTest {
private val sitePermissions = SitePermissions(origin = "", savedAt = 123)
private val appSettings = mockk<Settings>(relaxed = true)
private val permissionStorage = mockk<PermissionStorage>(relaxed = true)
private val trackingExceptions = mockk<ExceptionDomains>(relaxed = true)
private val reload = mockk<SessionUseCases.ReloadUrlUseCase>(relaxed = true)
private val addNewTab = mockk<TabsUseCases.AddNewTabUseCase>(relaxed = true)
private val requestPermissions = mockk<(Array<String>) -> Unit>(relaxed = true)
@ -61,6 +62,7 @@ class DefaultQuickSettingsControllerTest {
private val displayTrackingProtection = mockk<() -> Unit>(relaxed = true)
private val displayPermissions = mockk<() -> Unit>(relaxed = true)
private val dismiss = mockk<() -> Unit>(relaxed = true)
private val trackingProtectionUseCases = mockk<TrackingProtectionUseCases>(relaxed = true)
private val controller = DefaultQuickSettingsController(
context = context,
quickSettingsStore = store,
@ -70,32 +72,30 @@ class DefaultQuickSettingsControllerTest {
sitePermissions = sitePermissions,
settings = appSettings,
permissionStorage = permissionStorage,
trackingExceptions = trackingExceptions,
reload = reload,
addNewTab = addNewTab,
requestRuntimePermissions = requestPermissions,
reportSiteIssue = reportIssue,
displayTrackingProtection = displayTrackingProtection,
displayPermissions = displayPermissions,
dismiss = dismiss
dismiss = dismiss,
trackingProtectionUseCases = trackingProtectionUseCases
)
@Test
fun `handleTrackingProtectionToggled should toggle tracking and reload website`() {
val testWebsiteHost = "host.com"
val websiteHost = slot<String>()
val session = slot<Session>()
every { store.dispatch(any()) } returns mockk()
controller.handleTrackingProtectionToggled("https://$testWebsiteHost/page1", false)
controller.handleTrackingProtectionToggled(false)
verifyOrder {
trackingExceptions.toggle(capture(websiteHost))
trackingProtectionUseCases.addException(capture(session))
context.metrics.track(Event.TrackingProtectionException)
reload(capture(session))
}
assertAll {
assertThat(websiteHost.isCaptured).isTrue()
assertThat(websiteHost.captured).isEqualTo(testWebsiteHost)
assertThat(session.isCaptured).isTrue()
assertThat(session.captured).isEqualTo(browserSession)
}
@ -118,7 +118,8 @@ class DefaultQuickSettingsControllerTest {
@ExperimentalCoroutinesApi
fun `handleReportTrackingProblem should open a report issue webpage and dismiss when in normal mode`() {
val websiteWithIssuesUrl = "https://host.com/page1"
val testReportUrl = String.format(BrowserFragment.REPORT_SITE_ISSUE_URL, websiteWithIssuesUrl)
val testReportUrl =
String.format(BrowserFragment.REPORT_SITE_ISSUE_URL, websiteWithIssuesUrl)
val reportUrl = slot<String>()
// `handleReportTrackingProblem` will behave differently depending on `isCustomTabSession`
every { browserSession.isCustomTabSession() } returns false
@ -140,7 +141,8 @@ class DefaultQuickSettingsControllerTest {
@ExperimentalCoroutinesApi
fun `handleReportTrackingProblem should open a report issue in browser from custom tab and dismiss`() {
val websiteWithIssuesUrl = "https://host.com/page1"
val testReportUrl = String.format(BrowserFragment.REPORT_SITE_ISSUE_URL, websiteWithIssuesUrl)
val testReportUrl =
String.format(BrowserFragment.REPORT_SITE_ISSUE_URL, websiteWithIssuesUrl)
val reportUrl = slot<String>()
// `handleReportTrackingProblem` will behave differently depending on `isCustomTabSession`
every { browserSession.isCustomTabSession() } returns true
@ -237,7 +239,8 @@ class DefaultQuickSettingsControllerTest {
featureGranted.getCorrespondingPermission()
}
val permissionStatus = featureGranted.getActionLabel(context, sitePermissions, appSettings)
val permissionEnabled = featureGranted.shouldBeEnabled(context, sitePermissions, appSettings)
val permissionEnabled =
featureGranted.shouldBeEnabled(context, sitePermissions, appSettings)
val action = slot<QuickSettingsFragmentAction>()
every { store.dispatch(any()) } returns mockk()
@ -249,9 +252,15 @@ class DefaultQuickSettingsControllerTest {
assertAll {
assertThat(action.isCaptured).isTrue()
assertThat(action.captured).isInstanceOf(WebsitePermissionAction.TogglePermission::class)
assertThat((action.captured as WebsitePermissionAction.TogglePermission).websitePermission).isEqualTo(permission)
assertThat((action.captured as WebsitePermissionAction.TogglePermission).updatedStatus).isEqualTo(permissionStatus)
assertThat((action.captured as WebsitePermissionAction.TogglePermission).updatedEnabledStatus).isEqualTo(permissionEnabled)
assertThat((action.captured as WebsitePermissionAction.TogglePermission).websitePermission).isEqualTo(
permission
)
assertThat((action.captured as WebsitePermissionAction.TogglePermission).updatedStatus).isEqualTo(
permissionStatus
)
assertThat((action.captured as WebsitePermissionAction.TogglePermission).updatedEnabledStatus).isEqualTo(
permissionEnabled
)
}
}
@ -272,24 +281,25 @@ class DefaultQuickSettingsControllerTest {
@Test
@ExperimentalCoroutinesApi
fun `handlePermissionsChange should store the updated permission and reload webpage`() = runBlocking {
val testPermissions = mockk<SitePermissions>()
val permissions = slot<SitePermissions>()
val session = slot<Session>()
fun `handlePermissionsChange should store the updated permission and reload webpage`() =
runBlocking {
val testPermissions = mockk<SitePermissions>()
val permissions = slot<SitePermissions>()
val session = slot<Session>()
controller.handlePermissionsChange(testPermissions)
controller.handlePermissionsChange(testPermissions)
verifyOrder {
permissionStorage.updateSitePermissions(capture(permissions))
reload(capture(session))
verifyOrder {
permissionStorage.updateSitePermissions(capture(permissions))
reload(capture(session))
}
assertAll {
assertThat(permissions.isCaptured).isTrue()
assertThat(permissions.captured).isEqualTo(testPermissions)
assertThat(session.isCaptured).isTrue()
assertThat(session.captured).isEqualTo(browserSession)
}
}
assertAll {
assertThat(permissions.isCaptured).isTrue()
assertThat(permissions.captured).isEqualTo(testPermissions)
assertThat(session.isCaptured).isTrue()
assertThat(session.captured).isEqualTo(browserSession)
}
}
@Test
fun `WebsitePermission#getBackingFeature should return the PhoneFeature this permission is mapped from`() {

View File

@ -36,20 +36,15 @@ class QuickSettingsInteractorTest {
@Test
fun `onProtectionToggled should delegate the controller`() {
val websiteUrl = "https://host.com/page1"
val trackingEnabled = true
val url = slot<String>()
val trackingStatus = slot<Boolean>()
interactor.onProtectionToggled(websiteUrl, trackingEnabled)
interactor.onProtectionToggled(trackingEnabled)
verifyAll {
controller.handleTrackingProtectionToggled(capture(url), capture(trackingStatus))
controller.handleTrackingProtectionToggled(capture(trackingStatus))
}
assertAll {
assertThat(url.isCaptured).isTrue()
assertThat(url.captured).isEqualTo(websiteUrl)
assertThat(trackingStatus.isCaptured).isTrue()
assertThat(trackingStatus.captured).isEqualTo(trackingEnabled)
}

View File

@ -141,7 +141,7 @@ The following metrics are added to the ping:
| sync_auth.sign_up |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |User registered a new Firefox Account, and was signed into it |[1](https://github.com/mozilla-mobile/fenix/pull/4931#issuecomment-529740300)||2020-03-01 |
| tab.media_pause |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the pause icon on a tab from the home screen |[1](https://github.com/mozilla-mobile/fenix/pull/5266)||2020-03-01 |
| tab.media_play |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the play icon on a tab from the home screen |[1](https://github.com/mozilla-mobile/fenix/pull/5266)||2020-03-01 |
| tracking_protection.etp_setting_changed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user added a tracking protection exception through the TP toggle in the panel. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)|<ul><li>etp_setting: The new setting for ETP: strict, standard</li></ul>|2020-03-01 |
| tracking_protection.etp_setting_changed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user changed their tracking protection level setting to either strict or standard. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)|<ul><li>etp_setting: The new setting for ETP: strict, standard</li></ul>|2020-03-01 |
| tracking_protection.etp_settings |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user opened tracking protection settings through settings. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)||2020-03-01 |
| tracking_protection.etp_shield |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the tracking protection shield icon in toolbar. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)||2020-03-01 |
| tracking_protection.etp_tracker_list |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed into a list of categorized trackers in tracking protection panel. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)||2020-03-01 |