diff --git a/app/src/main/java/org/mozilla/fenix/settings/studies/StudiesAdapter.kt b/app/src/main/java/org/mozilla/fenix/settings/studies/StudiesAdapter.kt index 5fe74443d9..d08a1762d7 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/studies/StudiesAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/studies/StudiesAdapter.kt @@ -5,12 +5,15 @@ package org.mozilla.fenix.settings.studies import android.annotation.SuppressLint +import android.content.Context +import android.content.DialogInterface import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.annotation.StringRes import androidx.annotation.VisibleForTesting +import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter @@ -117,10 +120,32 @@ class StudiesAdapter( holder.summaryView.text = study.userFacingDescription holder.deleteButton.setOnClickListener { - studiesDelegate.onRemoveButtonClicked(study) + showDeleteDialog(holder.titleView.context, study) } } + @VisibleForTesting + internal fun showDeleteDialog(context: Context, study: EnrolledExperiment): AlertDialog { + val builder = AlertDialog.Builder(context) + .setPositiveButton( + R.string.studies_restart_dialog_ok + ) { dialog, _ -> + studiesDelegate.onRemoveButtonClicked(study) + dialog.dismiss() + } + .setNegativeButton( + R.string.studies_restart_dialog_cancel + ) { dialog: DialogInterface, _ -> + dialog.dismiss() + } + .setTitle(R.string.preference_experiments_2) + .setMessage(R.string.studies_restart_app) + .setCancelable(false) + val alertDialog: AlertDialog = builder.create() + alertDialog.show() + return alertDialog + } + internal fun createListWithSections(studies: List): List { val itemsWithSections = ArrayList() val activeStudies = ArrayList() diff --git a/app/src/main/java/org/mozilla/fenix/settings/studies/StudiesInteractor.kt b/app/src/main/java/org/mozilla/fenix/settings/studies/StudiesInteractor.kt index c859f4875d..46d4d87943 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/studies/StudiesInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/studies/StudiesInteractor.kt @@ -4,10 +4,12 @@ package org.mozilla.fenix.settings.studies +import androidx.annotation.VisibleForTesting import mozilla.components.service.nimbus.NimbusApi import org.mozilla.experiments.nimbus.internal.EnrolledExperiment import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.HomeActivity +import kotlin.system.exitProcess interface StudiesInteractor { /** @@ -35,5 +37,11 @@ class DefaultStudiesInteractor( override fun removeStudy(experiment: EnrolledExperiment) { experiments.optOut(experiment.slug) + killApplication() + } + + @VisibleForTesting + internal fun killApplication() { + exitProcess(0) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a3726e7c13..99e05a4ccd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -623,6 +623,12 @@ Firefox may install and run studies from time to time. Learn more + + The application will quit to apply changes + + OK + + Cancel diff --git a/app/src/test/java/org/mozilla/fenix/settings/studies/DefaultStudiesInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/settings/studies/DefaultStudiesInteractorTest.kt index 5384e80255..3b90fc4c0a 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/studies/DefaultStudiesInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/studies/DefaultStudiesInteractorTest.kt @@ -7,7 +7,10 @@ package org.mozilla.fenix.settings.studies import io.mockk.MockKAnnotations import io.mockk.every import io.mockk.impl.annotations.RelaxedMockK +import io.mockk.just import io.mockk.mockk +import io.mockk.runs +import io.mockk.spyk import io.mockk.verify import kotlinx.coroutines.ExperimentalCoroutinesApi import mozilla.components.service.nimbus.NimbusApi @@ -30,7 +33,7 @@ class DefaultStudiesInteractorTest { @Before fun setup() { MockKAnnotations.init(this) - interactor = DefaultStudiesInteractor(activity, experiments) + interactor = spyk(DefaultStudiesInteractor(activity, experiments)) } @Test @@ -48,6 +51,7 @@ class DefaultStudiesInteractorTest { val experiment = mockk(relaxed = true) every { experiment.slug } returns "slug" + every { interactor.killApplication() } just runs interactor.removeStudy(experiment) diff --git a/app/src/test/java/org/mozilla/fenix/settings/studies/StudiesAdapterTest.kt b/app/src/test/java/org/mozilla/fenix/settings/studies/StudiesAdapterTest.kt index 33b190cb71..c6b70d98a9 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/studies/StudiesAdapterTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/studies/StudiesAdapterTest.kt @@ -16,9 +16,9 @@ import io.mockk.mockk import io.mockk.runs import io.mockk.spyk import io.mockk.verify -import junit.framework.TestCase.assertTrue -import junit.framework.TestCase.assertFalse import junit.framework.TestCase.assertEquals +import junit.framework.TestCase.assertFalse +import junit.framework.TestCase.assertTrue import kotlinx.coroutines.ExperimentalCoroutinesApi import mozilla.components.support.test.robolectric.testContext import org.junit.Before @@ -69,7 +69,7 @@ class StudiesAdapterTest { fun `WHEN bindStudy THEN bind the study information`() { val holder = mockk() val study = mockk() - val titleView = mockk(relaxed = true) + val titleView = spyk(TextView(testContext)) val summaryView = mockk(relaxed = true) val deleteButton = spyk(MaterialButton(testContext)) @@ -82,6 +82,8 @@ class StudiesAdapterTest { adapter = spyk(StudiesAdapter(delegate, listOf(study), false)) + every { adapter.showDeleteDialog(any(), any()) } returns mockk() + adapter.bindStudy(holder, study) verify { @@ -92,7 +94,7 @@ class StudiesAdapterTest { deleteButton.performClick() verify { - delegate.onRemoveButtonClicked(study) + adapter.showDeleteDialog(any(), any()) } }