2
0
mirror of https://github.com/fork-maintainers/iceraven-browser synced 2024-11-11 13:11:01 +00:00

For #13507 - Adds tests for ReviewPromptController

This commit is contained in:
Jeff Boek 2020-08-25 21:46:25 -07:00
parent 56b730f0e8
commit c6687d976e
5 changed files with 162 additions and 15 deletions

View File

@ -7,6 +7,8 @@
<!-- The Sentry SDK is compiled against parts of the Java SDK that are not available in the Android SDK. <!-- The Sentry SDK is compiled against parts of the Java SDK that are not available in the Android SDK.
Let's just ignore issues in the Sentry code since that is a third-party dependency anyways. --> Let's just ignore issues in the Sentry code since that is a third-party dependency anyways. -->
<ignore path="**/sentry*.jar" /> <ignore path="**/sentry*.jar" />
<!-- Temporary until https://github.com/Kotlin/kotlinx.coroutines/issues/2004 is resolved. -->
<ignore path="**/kotlinx-coroutines-core-*.jar"/>
</issue> </issue>
<!-- Lints that don't apply to our translation process --> <!-- Lints that don't apply to our translation process -->
<issue id="MissingTranslation" severity="ignore" /> <issue id="MissingTranslation" severity="ignore" />

View File

@ -26,7 +26,7 @@ interface ReviewSettings {
*/ */
class FenixReviewSettings( class FenixReviewSettings(
val settings: Settings val settings: Settings
): ReviewSettings { ) : ReviewSettings {
override var numberOfAppLaunches: Int override var numberOfAppLaunches: Int
get() = settings.numberOfAppLaunches get() = settings.numberOfAppLaunches
set(value) { settings.numberOfAppLaunches = value } set(value) { settings.numberOfAppLaunches = value }
@ -43,14 +43,16 @@ class FenixReviewSettings(
class ReviewPromptController( class ReviewPromptController(
private val context: Context, private val context: Context,
private val reviewSettings: ReviewSettings, private val reviewSettings: ReviewSettings,
private val timeNowInMillis: () -> Long = { System.currentTimeMillis() } private val timeNowInMillis: () -> Long = { System.currentTimeMillis() },
private val tryPromptReview: suspend (Activity) -> Unit = {
val manager = ReviewManagerFactory.create(context)
val reviewInfo = manager.requestReview()
manager.launchReview(it, reviewInfo)
}
) { ) {
suspend fun promptReview(activity: Activity) { suspend fun promptReview(activity: Activity) {
if (shouldShowPrompt()) { if (shouldShowPrompt()) {
val manager = ReviewManagerFactory.create(context) tryPromptReview(activity)
val reviewInfo = manager.requestReview()
manager.launchReview(activity, reviewInfo)
reviewSettings.lastReviewPromptTimeInMillis = timeNowInMillis() reviewSettings.lastReviewPromptTimeInMillis = timeNowInMillis()
} }
} }
@ -63,14 +65,18 @@ class ReviewPromptController(
fun shouldShowPrompt(): Boolean { fun shouldShowPrompt(): Boolean {
if (!reviewSettings.isDefaultBrowser) { return false } if (!reviewSettings.isDefaultBrowser) { return false }
val hasOpenedFiveTimes = reviewSettings.numberOfAppLaunches >= 5 val hasOpenedFiveTimes = reviewSettings.numberOfAppLaunches >= NUMBER_OF_LAUNCHES_REQUIRED
val apprxFourMonthsAgo = timeNowInMillis() - (APPRX_MONTH_IN_MILLIS * 4) val now = timeNowInMillis()
val hasNotBeenPromptedLastFourMonths = reviewSettings.lastReviewPromptTimeInMillis <= apprxFourMonthsAgo val apprxFourMonthsAgo = now - (APPRX_MONTH_IN_MILLIS * NUMBER_OF_MONTHS_TO_PASS)
val lastPrompt = reviewSettings.lastReviewPromptTimeInMillis
val hasNotBeenPromptedLastFourMonths = lastPrompt == 0L || lastPrompt <= apprxFourMonthsAgo
return hasOpenedFiveTimes && hasNotBeenPromptedLastFourMonths return hasOpenedFiveTimes && hasNotBeenPromptedLastFourMonths
} }
companion object { companion object {
private const val APPRX_MONTH_IN_MILLIS: Long = 1000L * 60L * 60L * 24L * 30L private const val APPRX_MONTH_IN_MILLIS: Long = 1000L * 60L * 60L * 24L * 30L
private const val NUMBER_OF_LAUNCHES_REQUIRED = 5
private const val NUMBER_OF_MONTHS_TO_PASS = 4
} }
} }

View File

@ -42,9 +42,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.android.play.core.ktx.launchReview
import com.google.android.play.core.ktx.requestReview
import com.google.android.play.core.review.ReviewManagerFactory
import kotlinx.android.synthetic.main.fragment_home.* import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.fragment_home.view.* import kotlinx.android.synthetic.main.fragment_home.view.*
import kotlinx.android.synthetic.main.no_collections_message.view.* import kotlinx.android.synthetic.main.no_collections_message.view.*

View File

@ -12,7 +12,6 @@ import android.content.SharedPreferences
import android.content.pm.ShortcutManager import android.content.pm.ShortcutManager
import android.os.Build import android.os.Build
import android.view.accessibility.AccessibilityManager import android.view.accessibility.AccessibilityManager
import androidx.annotation.RequiresApi
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting.PRIVATE import androidx.annotation.VisibleForTesting.PRIVATE
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
@ -40,7 +39,6 @@ import org.mozilla.fenix.settings.logins.SavedLoginsSortingStrategyMenu
import org.mozilla.fenix.settings.logins.SortingStrategy import org.mozilla.fenix.settings.logins.SortingStrategy
import org.mozilla.fenix.settings.registerOnSharedPreferenceChangeListener import org.mozilla.fenix.settings.registerOnSharedPreferenceChangeListener
import java.security.InvalidParameterException import java.security.InvalidParameterException
import java.time.LocalDate
private const val AUTOPLAY_USER_SETTING = "AUTOPLAY_USER_SETTING" private const val AUTOPLAY_USER_SETTING = "AUTOPLAY_USER_SETTING"

View File

@ -0,0 +1,144 @@
/* 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.components
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest
import mozilla.components.support.test.robolectric.testContext
import org.junit.Test
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Assert.assertFalse
import org.junit.runner.RunWith
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
class TestReviewSettings(
override var numberOfAppLaunches: Int = 0,
var isDefault: Boolean = false,
override var lastReviewPromptTimeInMillis: Long = 0
) : ReviewSettings {
override val isDefaultBrowser: Boolean
get() = isDefault
}
@ExperimentalCoroutinesApi
@RunWith(FenixRobolectricTestRunner::class)
class ReviewPromptControllerTest {
@Test
fun promptReviewDoesNotSetMillis() = runBlockingTest {
var promptWasCalled = false
val settings = TestReviewSettings(
numberOfAppLaunches = 5,
isDefault = false,
lastReviewPromptTimeInMillis = 0L
)
val controller = ReviewPromptController(
testContext,
settings,
{ 100L },
{ promptWasCalled = true }
)
controller.promptReview(HomeActivity())
assertEquals(settings.lastReviewPromptTimeInMillis, 0L)
assertFalse(promptWasCalled)
}
@Test
fun promptReviewSetsMillisIfSuccessful() = runBlockingTest {
var promptWasCalled = false
val settings = TestReviewSettings(
numberOfAppLaunches = 5,
isDefault = true,
lastReviewPromptTimeInMillis = 0L
)
val controller = ReviewPromptController(
testContext,
settings,
{ 100L },
{ promptWasCalled = true }
)
controller.promptReview(HomeActivity())
assertEquals(100L, settings.lastReviewPromptTimeInMillis)
assertTrue(promptWasCalled)
}
@Test
fun trackApplicationLaunch() {
val settings = TestReviewSettings(
numberOfAppLaunches = 4,
isDefault = true,
lastReviewPromptTimeInMillis = 0L
)
val controller = ReviewPromptController(
testContext,
settings,
{ 100L }
)
assertEquals(4, settings.numberOfAppLaunches)
controller.trackApplicationLaunch()
assertEquals(5, settings.numberOfAppLaunches)
}
@Test
fun shouldShowPrompt() {
val settings = TestReviewSettings(
numberOfAppLaunches = 5,
isDefault = true,
lastReviewPromptTimeInMillis = 0L
)
val controller = ReviewPromptController(
testContext,
settings,
{ 1598416882805L }
)
// Test first success criteria
assertTrue(controller.shouldShowPrompt())
// Test with last prompt approx 4 months earlier
settings.apply {
numberOfAppLaunches = 5
isDefault = true
lastReviewPromptTimeInMillis = 1588048882804L
}
assertTrue(controller.shouldShowPrompt())
// Test without being the default browser
settings.apply {
numberOfAppLaunches = 5
isDefault = false
lastReviewPromptTimeInMillis = 1595824882805L
}
assertFalse(controller.shouldShowPrompt())
// Test with number of app launches < 5
settings.apply {
numberOfAppLaunches = 4
isDefault = true
lastReviewPromptTimeInMillis = 0L
}
assertFalse(controller.shouldShowPrompt())
// Test with last prompt less than 4 months ago
settings.apply {
numberOfAppLaunches = 5
isDefault = true
lastReviewPromptTimeInMillis = 1595824882905L
}
assertFalse(controller.shouldShowPrompt())
}
}