For #9294: Add option to clear current site data in quick settings dialog.
parent
e150f6118b
commit
9bfc94b793
@ -0,0 +1,117 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.settings.quicksettings
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.core.view.isVisible
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.mozilla.fenix.FeatureFlags
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.databinding.QuicksettingsClearSiteDataBinding
|
||||
import org.mozilla.fenix.ext.components
|
||||
|
||||
/**
|
||||
* Contract declaring all possible user interactions with [ClearSiteDataView].
|
||||
*/
|
||||
interface ClearSiteDataViewInteractor {
|
||||
/**
|
||||
* Shows the confirmation dialog to clear site data for [baseDomain].
|
||||
*/
|
||||
fun onClearSiteDataClicked(baseDomain: String)
|
||||
}
|
||||
|
||||
/**
|
||||
* MVI View to access the dialog to clear site cookies and data.
|
||||
*
|
||||
* @param containerView [ViewGroup] in which this View will inflate itself.
|
||||
* @param interactor [TrackingProtectionInteractor] which will have delegated to all user
|
||||
* interactions.
|
||||
*/
|
||||
class ClearSiteDataView(
|
||||
val context: Context,
|
||||
private val ioScope: CoroutineScope,
|
||||
val containerView: ViewGroup,
|
||||
val containerDivider: View,
|
||||
val interactor: ClearSiteDataViewInteractor
|
||||
) {
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
lateinit var websiteUrl: String
|
||||
|
||||
val binding = QuicksettingsClearSiteDataBinding.inflate(
|
||||
LayoutInflater.from(context),
|
||||
containerView,
|
||||
true
|
||||
)
|
||||
|
||||
fun update(webInfoState: WebsiteInfoState) {
|
||||
if (!FeatureFlags.showClearSiteData) {
|
||||
setVisibility(false)
|
||||
return
|
||||
}
|
||||
|
||||
websiteUrl = webInfoState.websiteUrl
|
||||
|
||||
setVisibility(true)
|
||||
binding.clearSiteData.setOnClickListener {
|
||||
askToClear()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setVisibility(visible: Boolean) {
|
||||
binding.root.isVisible = visible
|
||||
containerDivider.isVisible = visible
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
internal fun askToClear() {
|
||||
|
||||
ioScope.launch {
|
||||
val publicSuffixList = context.components.publicSuffixList
|
||||
val host = websiteUrl.toUri().host.orEmpty()
|
||||
val domain = publicSuffixList.getPublicSuffixPlusOne(host).await()
|
||||
|
||||
domain?.let { baseDomain ->
|
||||
launch(Dispatchers.Main) {
|
||||
showConfirmationDialog(baseDomain)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showConfirmationDialog(baseDomain: String) {
|
||||
AlertDialog.Builder(context).apply {
|
||||
setMessage(
|
||||
HtmlCompat.fromHtml(
|
||||
context.getString(
|
||||
R.string.confirm_clear_site_data,
|
||||
baseDomain
|
||||
),
|
||||
HtmlCompat.FROM_HTML_MODE_LEGACY
|
||||
)
|
||||
)
|
||||
|
||||
setNegativeButton(R.string.delete_browsing_data_prompt_cancel) { it: DialogInterface, _ ->
|
||||
it.cancel()
|
||||
}
|
||||
|
||||
setPositiveButton(R.string.delete_browsing_data_prompt_allow) { it: DialogInterface, _ ->
|
||||
it.dismiss()
|
||||
interactor.onClearSiteDataClicked(baseDomain)
|
||||
}
|
||||
create()
|
||||
}.show()
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/website_clear_site_data"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/clearSiteData"
|
||||
style="@style/QuickSettingsLargeText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/quicksettings_item_height"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:text="@string/clear_site_data" />
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,59 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.settings.quicksettings
|
||||
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.mockk
|
||||
import io.mockk.spyk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.test.TestCoroutineScope
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.databinding.QuicksettingsClearSiteDataBinding
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class ClearSiteDataViewTest {
|
||||
private lateinit var view: ClearSiteDataView
|
||||
private lateinit var binding: QuicksettingsClearSiteDataBinding
|
||||
private lateinit var interactor: ClearSiteDataViewInteractor
|
||||
private val coroutinesScope = TestCoroutineScope()
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockKAnnotations.init(this)
|
||||
interactor = mockk(relaxed = true)
|
||||
view = spyk(
|
||||
ClearSiteDataView(
|
||||
testContext,
|
||||
coroutinesScope,
|
||||
FrameLayout(testContext),
|
||||
View(testContext),
|
||||
interactor
|
||||
)
|
||||
)
|
||||
binding = view.binding
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clear site`() {
|
||||
val state = WebsiteInfoState(
|
||||
websiteUrl = "https://developers.mozilla.org",
|
||||
websiteTitle = "Mozilla",
|
||||
websiteSecurityUiValues = WebsiteSecurityUiValues.SECURE,
|
||||
certificateName = "Certificate"
|
||||
)
|
||||
|
||||
view.update(state)
|
||||
|
||||
binding.clearSiteData.callOnClick()
|
||||
|
||||
verify { view.askToClear() }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue