Imporved the showing of donation popup

This commit is contained in:
MohitMaliFtechiz 2024-11-12 17:43:51 +05:30 committed by Kelson
parent 44ad90e3a3
commit 9b29b07dcb
2 changed files with 152 additions and 23 deletions

View File

@ -19,11 +19,12 @@
package org.kiwix.kiwixmobile.core.utils package org.kiwix.kiwixmobile.core.utils
import android.app.Activity import android.app.Activity
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.getPackageInformation
import org.kiwix.kiwixmobile.core.dao.NewBookDao import org.kiwix.kiwixmobile.core.dao.NewBookDao
import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.isCustomApp import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.isCustomApp
import javax.inject.Inject import javax.inject.Inject
const val THREE_DAYS_IN_MILLISECONDS = 3 * 24 * 60 * 60 * 1000L
const val THREE_MONTHS_IN_MILLISECONDS = 90 * 24 * 60 * 60 * 1000L const val THREE_MONTHS_IN_MILLISECONDS = 90 * 24 * 60 * 60 * 1000L
class DonationDialogHandler @Inject constructor( class DonationDialogHandler @Inject constructor(
@ -41,26 +42,35 @@ class DonationDialogHandler @Inject constructor(
suspend fun attemptToShowDonationPopup() { suspend fun attemptToShowDonationPopup() {
val currentMilliSeconds = System.currentTimeMillis() val currentMilliSeconds = System.currentTimeMillis()
val lastPopupMillis = sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds val lastPopupMillis = sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds
val timeDifference = currentMilliSeconds - lastPopupMillis
if (shouldShowInitialPopup(lastPopupMillis) || timeDifference >= THREE_MONTHS_IN_MILLISECONDS) { val shouldShowPopup = (lastPopupMillis == 0L && shouldShowInitialPopup(currentMilliSeconds)) ||
if (isZimFilesAvailableInLibrary() && isTimeToShowDonation(currentMilliSeconds)) { isThreeMonthsElapsed(currentMilliSeconds, lastPopupMillis)
showDonationDialogCallback?.showDonationDialog()
resetDonateLater() if (shouldShowPopup &&
} isZimFilesAvailableInLibrary() &&
isTimeToShowDonation(currentMilliSeconds)
) {
showDonationDialogCallback?.showDonationDialog()
resetDonateLater()
} }
} }
private suspend fun shouldShowInitialPopup(lastPopupMillis: Long): Boolean = fun shouldShowInitialPopup(currentMillis: Long): Boolean {
lastPopupMillis == 0L && isZimFilesAvailableInLibrary() val appInstallTime =
activity.packageManager.getPackageInformation(activity.packageName, ZERO).firstInstallTime
return isThreeMonthsElapsed(currentMillis, appInstallTime)
}
private fun isTimeToShowDonation(currentMillis: Long): Boolean = fun isTimeToShowDonation(currentMillis: Long): Boolean {
isLaterNotClicked() || isLaterPeriodOver(currentMillis) val lastLaterClick = sharedPreferenceUtil.laterClickedMilliSeconds
return lastLaterClick == 0L ||
isThreeMonthsElapsed(currentMillis, lastLaterClick)
}
private fun isLaterNotClicked(): Boolean = sharedPreferenceUtil.laterClickedMilliSeconds == 0L fun isThreeMonthsElapsed(currentMilliSeconds: Long, lastPopupMillis: Long): Boolean {
if (lastPopupMillis == 0L) return false
private fun isLaterPeriodOver(currentMillis: Long): Boolean { val timeDifference = currentMilliSeconds - lastPopupMillis
val timeDifference = currentMillis - sharedPreferenceUtil.laterClickedMilliSeconds return timeDifference >= THREE_MONTHS_IN_MILLISECONDS
return timeDifference >= THREE_DAYS_IN_MILLISECONDS
} }
suspend fun isZimFilesAvailableInLibrary(): Boolean = suspend fun isZimFilesAvailableInLibrary(): Boolean =

View File

@ -19,11 +19,15 @@
package org.kiwix.kiwixmobile.core.utils package org.kiwix.kiwixmobile.core.utils
import android.app.Activity import android.app.Activity
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import io.mockk.Called
import io.mockk.Runs import io.mockk.Runs
import io.mockk.coEvery import io.mockk.coEvery
import io.mockk.every import io.mockk.every
import io.mockk.just import io.mockk.just
import io.mockk.mockk import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify import io.mockk.verify
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
@ -31,7 +35,9 @@ import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.getPackageInformation
import org.kiwix.kiwixmobile.core.dao.NewBookDao import org.kiwix.kiwixmobile.core.dao.NewBookDao
import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions
@ExperimentalCoroutinesApi @ExperimentalCoroutinesApi
@ -41,10 +47,14 @@ class DonationDialogHandlerTest {
private lateinit var newBookDao: NewBookDao private lateinit var newBookDao: NewBookDao
private lateinit var donationDialogHandler: DonationDialogHandler private lateinit var donationDialogHandler: DonationDialogHandler
private lateinit var showDonationDialogCallback: DonationDialogHandler.ShowDonationDialogCallback private lateinit var showDonationDialogCallback: DonationDialogHandler.ShowDonationDialogCallback
private lateinit var packageManager: PackageManager
@BeforeEach @BeforeEach
fun setup() { fun setup() {
activity = mockk(relaxed = true) activity = mockk(relaxed = true)
packageManager = mockk(relaxed = true)
every { activity.packageManager } returns packageManager
every { activity.packageName } returns "org.kiwix.kiwixmobile"
sharedPreferenceUtil = mockk(relaxed = true) sharedPreferenceUtil = mockk(relaxed = true)
newBookDao = mockk(relaxed = true) newBookDao = mockk(relaxed = true)
showDonationDialogCallback = mockk(relaxed = true) showDonationDialogCallback = mockk(relaxed = true)
@ -54,15 +64,51 @@ class DonationDialogHandlerTest {
} }
@Test @Test
fun `test should show initial popup`() = runTest { fun `should show initial donation popup when app is three month old`() = runTest {
donationDialogHandler = spyk(donationDialogHandler)
every { sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds } returns 0L every { sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds } returns 0L
every { sharedPreferenceUtil.laterClickedMilliSeconds } returns 0L
coEvery { newBookDao.getBooks() } returns listOf(mockk()) coEvery { newBookDao.getBooks() } returns listOf(mockk())
every {
donationDialogHandler.shouldShowInitialPopup(any())
} returns true
donationDialogHandler.attemptToShowDonationPopup() donationDialogHandler.attemptToShowDonationPopup()
verify { showDonationDialogCallback.showDonationDialog() } verify { showDonationDialogCallback.showDonationDialog() }
} }
@Test @Test
fun `test should not show popup when time difference is less than 3 months`() = runTest { fun `should not show donation popup if app is not three month old`() = runTest {
every { sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds } returns 0L
coEvery { newBookDao.getBooks() } returns listOf(mockk())
val currentMillis = System.currentTimeMillis()
val installTime = currentMillis - 1000
val packageInfo = PackageInfo().apply {
firstInstallTime = installTime
}
every {
packageManager.getPackageInformation(activity.packageName, ZERO)
} returns packageInfo
donationDialogHandler.attemptToShowDonationPopup()
verify { showDonationDialogCallback wasNot Called }
}
@Test
fun `should not show donation popup when no ZIM files available in library`() = runTest {
every { sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds } returns 0L
coEvery { newBookDao.getBooks() } returns emptyList()
val currentMillis = System.currentTimeMillis()
val threeMonthsAgo = currentMillis - THREE_MONTHS_IN_MILLISECONDS
val packageInfo = PackageInfo().apply {
firstInstallTime = threeMonthsAgo
}
every { packageManager.getPackageInformation(activity.packageName, ZERO) } returns packageInfo
donationDialogHandler.attemptToShowDonationPopup()
verify { showDonationDialogCallback wasNot Called }
}
@Test
fun `should not show popup if time since last popup is less than three month`() = runTest {
val currentMilliSeconds = System.currentTimeMillis() val currentMilliSeconds = System.currentTimeMillis()
every { every {
sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds
@ -73,7 +119,7 @@ class DonationDialogHandlerTest {
} }
@Test @Test
fun `test should show popup when time difference is more than 3 months`() = runTest { fun `should show donation popup if time since last popup exceeds three months`() = runTest {
val currentMilliSeconds = System.currentTimeMillis() val currentMilliSeconds = System.currentTimeMillis()
every { every {
sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds
@ -84,7 +130,39 @@ class DonationDialogHandlerTest {
} }
@Test @Test
fun `test donate later saves the correct time`() { fun `test should show donation popup when later clicked time exceeds three months`() = runTest {
donationDialogHandler = spyk(donationDialogHandler)
val currentMilliSeconds = System.currentTimeMillis()
every {
sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds
} returns 0L
every { donationDialogHandler.shouldShowInitialPopup(any()) } returns true
coEvery { newBookDao.getBooks() } returns listOf(mockk())
every {
sharedPreferenceUtil.laterClickedMilliSeconds
} returns currentMilliSeconds - (THREE_MONTHS_IN_MILLISECONDS + 1000)
donationDialogHandler.attemptToShowDonationPopup()
verify { showDonationDialogCallback.showDonationDialog() }
}
@Test
fun `test should show popup if later clicked time is less than three months`() = runTest {
donationDialogHandler = spyk(donationDialogHandler)
val currentMilliSeconds = System.currentTimeMillis()
every {
sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds
} returns 0L
every { donationDialogHandler.shouldShowInitialPopup(any()) } returns true
coEvery { newBookDao.getBooks() } returns listOf(mockk())
every {
sharedPreferenceUtil.laterClickedMilliSeconds
} returns currentMilliSeconds - 10000L
donationDialogHandler.attemptToShowDonationPopup()
verify { showDonationDialogCallback wasNot Called }
}
@Test
fun `donate later saves the correct time`() {
val currentMilliSeconds = System.currentTimeMillis() val currentMilliSeconds = System.currentTimeMillis()
every { sharedPreferenceUtil.laterClickedMilliSeconds = any() } just Runs every { sharedPreferenceUtil.laterClickedMilliSeconds = any() } just Runs
donationDialogHandler.donateLater(currentMilliSeconds) donationDialogHandler.donateLater(currentMilliSeconds)
@ -92,14 +170,55 @@ class DonationDialogHandlerTest {
} }
@Test @Test
fun `test reset donate later sets value to zero`() { fun `reset donate later sets value to zero`() {
every { sharedPreferenceUtil.laterClickedMilliSeconds = 0L } just Runs every { sharedPreferenceUtil.laterClickedMilliSeconds = 0L } just Runs
donationDialogHandler.resetDonateLater() donationDialogHandler.resetDonateLater()
verify { sharedPreferenceUtil.laterClickedMilliSeconds = 0L } verify { sharedPreferenceUtil.laterClickedMilliSeconds = 0L }
} }
@Test @Test
fun `test isZimFilesAvailableInLibrary returns true when isCustomApp is true`() = runTest { fun `updateLastDonationPopupShownTime sets correct time`() {
every { sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds = any() } just Runs
val currentTime = System.currentTimeMillis()
donationDialogHandler.updateLastDonationPopupShownTime()
verify { sharedPreferenceUtil.lastDonationPopupShownInMilliSeconds = more(currentTime - 1000) }
}
@Test
fun `isTimeToShowDonation should returns false when laterClicked time is recent`() {
val currentMillis = System.currentTimeMillis()
every { sharedPreferenceUtil.laterClickedMilliSeconds } returns currentMillis - 1000
val result = donationDialogHandler.isTimeToShowDonation(currentMillis)
assertFalse(result)
}
@Test
fun `test isTimeToShowDonation should returns true if laterClicked time is over three month`() {
val currentMillis = System.currentTimeMillis()
every {
sharedPreferenceUtil.laterClickedMilliSeconds
} returns currentMillis - THREE_MONTHS_IN_MILLISECONDS
val result = donationDialogHandler.isTimeToShowDonation(currentMillis)
assertTrue(result)
}
@Test
fun `isThreeMonthsElapsed should return false when lastPopupMillis is zero`() {
val currentMillis = System.currentTimeMillis()
val result = donationDialogHandler.isThreeMonthsElapsed(currentMillis, 0L)
assertFalse(result)
}
@Test
fun `isThreeMonthsElapsed returns true when lastPopup shows three month before`() {
val currentMillis = System.currentTimeMillis()
val lastPopupMillis = currentMillis - THREE_MONTHS_IN_MILLISECONDS
val result = donationDialogHandler.isThreeMonthsElapsed(currentMillis, lastPopupMillis)
assertTrue(result)
}
@Test
fun `isZimFilesAvailableInLibrary returns true when isCustomApp is true`() = runTest {
with(mockk<ActivityExtensions>()) { with(mockk<ActivityExtensions>()) {
every { activity.packageName } returns "org.kiwix.kiwixcustom" every { activity.packageName } returns "org.kiwix.kiwixcustom"
every { activity.isCustomApp() } returns true every { activity.isCustomApp() } returns true
@ -109,7 +228,7 @@ class DonationDialogHandlerTest {
} }
@Test @Test
fun `test isZimFilesAvailableInLibrary returns false when no books and isCustomApp is false`() = fun `isZimFilesAvailableInLibrary returns false when no books and isCustomApp is false`() =
runTest { runTest {
with(mockk<ActivityExtensions>()) { with(mockk<ActivityExtensions>()) {
every { activity.packageName } returns "org.kiwix.kiwixmobile" every { activity.packageName } returns "org.kiwix.kiwixmobile"