Application expired check

This commit is contained in:
Milos Kozak 2021-10-16 13:02:31 +02:00
parent 1f65ee38c7
commit dabf4bf33c
8 changed files with 255 additions and 304 deletions

View file

@ -3,15 +3,12 @@ package info.nightscout.androidaps.plugins.constraints.versionChecker
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.BuildConfig import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.interfaces.Constraints
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.extensions.daysToMillis import info.nightscout.androidaps.utils.extensions.daysToMillis
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -27,8 +24,11 @@ class VersionCheckerPlugin @Inject constructor(
resourceHelper: ResourceHelper, resourceHelper: ResourceHelper,
private val versionCheckerUtils: VersionCheckerUtils, private val versionCheckerUtils: VersionCheckerUtils,
val rxBus: RxBus, val rxBus: RxBus,
aapsLogger: AAPSLogger aapsLogger: AAPSLogger,
) : PluginBase(PluginDescription() private val config: Config,
private val dateUtil: DateUtil
) : PluginBase(
PluginDescription()
.mainType(PluginType.CONSTRAINTS) .mainType(PluginType.CONSTRAINTS)
.neverVisible(true) .neverVisible(true)
.alwaysEnabled(true) .alwaysEnabled(true)
@ -50,6 +50,7 @@ class VersionCheckerPlugin @Inject constructor(
} }
companion object { companion object {
private val WARN_EVERY: Long private val WARN_EVERY: Long
get() = TimeUnit.DAYS.toMillis(1) get() = TimeUnit.DAYS.toMillis(1)
} }
@ -57,10 +58,12 @@ class VersionCheckerPlugin @Inject constructor(
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> { override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
checkWarning() checkWarning()
versionCheckerUtils.triggerCheckVersion() versionCheckerUtils.triggerCheckVersion()
return if (isOldVersion(gracePeriod.veryOld.daysToMillis())) if (isOldVersion(gracePeriod.veryOld.daysToMillis()))
value.set(aapsLogger,false, resourceHelper.gs(R.string.very_old_version), this) value[aapsLogger, false, resourceHelper.gs(R.string.very_old_version)] = this
else val endDate = sp.getLong(resourceHelper.gs(info.nightscout.androidaps.core.R.string.key_app_expiration) + "_" + config.VERSION_NAME, 0)
value if (endDate != 0L && dateUtil.now() > endDate)
value[aapsLogger, false, resourceHelper.gs(R.string.application_expired)] = this
return value
} }
private fun checkWarning() { private fun checkWarning() {
@ -77,7 +80,8 @@ class VersionCheckerPlugin @Inject constructor(
sp.putLong(R.string.key_last_versionchecker_plugin_warning, now) sp.putLong(R.string.key_last_versionchecker_plugin_warning, now)
//notify //notify
val message = resourceHelper.gs(R.string.new_version_warning, val message = resourceHelper.gs(
R.string.new_version_warning,
((now - sp.getLong(R.string.key_last_time_this_version_detected, now)) / 1L.daysToMillis().toDouble()).roundToInt(), ((now - sp.getLong(R.string.key_last_time_this_version_detected, now)) / 1L.daysToMillis().toDouble()).roundToInt(),
gracePeriod.old, gracePeriod.old,
gracePeriod.veryOld gracePeriod.veryOld
@ -85,6 +89,16 @@ class VersionCheckerPlugin @Inject constructor(
val notification = Notification(Notification.OLD_VERSION, message, Notification.NORMAL) val notification = Notification(Notification.OLD_VERSION, message, Notification.NORMAL)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
} }
val endDate = sp.getLong(resourceHelper.gs(info.nightscout.androidaps.core.R.string.key_app_expiration) + "_" + config.VERSION_NAME, 0)
if (endDate != 0L && dateUtil.now() > endDate && shouldWarnAgain(now)) {
// store last notification time
sp.putLong(R.string.key_last_versionchecker_plugin_warning, now)
//notify
val notification = Notification(Notification.VERSION_EXPIRE, resourceHelper.gs(R.string.application_expired), Notification.URGENT)
rxBus.send(EventNewNotification(notification))
}
} }
private fun shouldWarnAgain(now: Long) = private fun shouldWarnAgain(now: Long) =

View file

@ -902,6 +902,7 @@
<string name="old_version">old version</string> <string name="old_version">old version</string>
<string name="very_old_version">very old version</string> <string name="very_old_version">very old version</string>
<string name="application_expired">Application expired</string>
<string name="new_version_warning">New version for at least %1$d days available! Fallback to LGS after %2$d days, loop will be disabled after %3$d days</string> <string name="new_version_warning">New version for at least %1$d days available! Fallback to LGS after %2$d days, loop will be disabled after %3$d days</string>
<string name="twohours">2h</string> <string name="twohours">2h</string>

View file

@ -1,5 +1,8 @@
package info.nightscout.androidaps.plugins.constraints.versionChecker package info.nightscout.androidaps.plugins.constraints.versionChecker
import org.joda.time.DateTime
import org.joda.time.LocalDate
import org.junit.Assert
import org.junit.Assert.* import org.junit.Assert.*
import org.junit.Test import org.junit.Test
@ -17,4 +20,24 @@ class AllowedVersionsTest {
assertEquals("2.8.2", AllowedVersions().findByApi(definition, 27)?.getString("supported")) assertEquals("2.8.2", AllowedVersions().findByApi(definition, 27)?.getString("supported"))
assertEquals("2.8.2", AllowedVersions().findByApi(definition, 28)?.getString("supported")) assertEquals("2.8.2", AllowedVersions().findByApi(definition, 28)?.getString("supported"))
} }
@Test
fun findByVersionTest() {
val definition = AllowedVersions().generateSupportedVersions()
assertNull(AllowedVersions().findByVersion(definition, "2.6.0"))
assertTrue(AllowedVersions().findByVersion(definition, "2.9.0-beta1")?.has("endDate") ?: false)
assertEquals("2021-11-07", AllowedVersions().findByVersion(definition, "2.9.0-beta1")?.getString("endDate"))
}
@Test
fun endDateToMilliseconds() {
val definition = AllowedVersions().generateSupportedVersions()
val endDate = AllowedVersions().endDateToMilliseconds(AllowedVersions().findByVersion(definition, "2.9.0-beta1")?.getString("endDate") ?: "1000/01/01")
val dateTime = LocalDate(endDate)
assertEquals(2021, dateTime.year)
assertEquals(11, dateTime.monthOfYear)
assertEquals(7, dateTime.dayOfMonth)
assertNull(AllowedVersions().endDateToMilliseconds("abdef"))
}
} }

View file

@ -1,13 +1,16 @@
package info.nightscout.androidaps.plugins.constraints.versionChecker package info.nightscout.androidaps.plugins.constraints.versionChecker
import org.joda.time.LocalDate
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import java.lang.Exception
class AllowedVersions { class AllowedVersions {
fun generateSupportedVersions(): String = fun generateSupportedVersions(): String =
JSONArray() JSONArray()
// Android API versions
.put(JSONObject().apply { .put(JSONObject().apply {
put("minAndroid", 1) // 1.0 put("minAndroid", 1) // 1.0
put("maxAndroid", 23) // 6.0.1 put("maxAndroid", 23) // 6.0.1
@ -27,6 +30,15 @@ class AllowedVersions {
put("maxAndroid", 99) put("maxAndroid", 99)
put("supported", "2.8.2") put("supported", "2.8.2")
}) })
// Version time limitation
.put(JSONObject().apply {
put("endDate", "2021-11-07")
put("version", "2.9.0-beta1")
})
.put(JSONObject().apply {
put("endDate", "2021-11-07")
put("version", "3.0-beta1")
})
.toString() .toString()
fun findByApi(definition: String?, api: Int): JSONObject? { fun findByApi(definition: String?, api: Int): JSONObject? {
@ -35,6 +47,7 @@ class AllowedVersions {
val array = JSONArray(definition) val array = JSONArray(definition)
for (i in 0 until array.length()) { for (i in 0 until array.length()) {
val record = array[i] as JSONObject val record = array[i] as JSONObject
if (record.has("minAndroid") && record.has("maxAndroid"))
if (api in record.getInt("minAndroid")..record.getInt("maxAndroid")) return record if (api in record.getInt("minAndroid")..record.getInt("maxAndroid")) return record
} }
} catch (e: JSONException) { } catch (e: JSONException) {
@ -42,4 +55,26 @@ class AllowedVersions {
return null return null
} }
fun findByVersion(definition: String?, version: String): JSONObject? {
if (definition == null) return null
try {
val array = JSONArray(definition)
for (i in 0 until array.length()) {
val record = array[i] as JSONObject
if (record.has("endDate") && record.has("version"))
if (version == record.getString("version")) return record
}
} catch (e: JSONException) {
}
return null
}
fun endDateToMilliseconds(endDate: String): Long? {
try {
val dateTime = LocalDate.parse(endDate)
return dateTime.toDate().time
} catch (ignored: Exception) {
}
return null
}
} }

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.plugins.constraints.versionChecker package info.nightscout.androidaps.plugins.constraints.versionChecker
import android.content.Context
import android.os.Build import android.os.Build
import info.nightscout.androidaps.core.R import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
@ -10,6 +9,7 @@ import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.receivers.ReceiverStatusStore import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import java.io.IOException import java.io.IOException
@ -20,13 +20,13 @@ import javax.inject.Singleton
@Singleton @Singleton
class VersionCheckerUtils @Inject constructor( class VersionCheckerUtils @Inject constructor(
val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
val sp: SP, private val sp: SP,
val resourceHelper: ResourceHelper, private val resourceHelper: ResourceHelper,
val rxBus: RxBus, private val rxBus: RxBus,
private val config: Config, private val config: Config,
val context: Context, private val receiverStatusStore: ReceiverStatusStore,
val receiverStatusStore: ReceiverStatusStore private val dateUtil: DateUtil
) { ) {
fun isConnected(): Boolean = receiverStatusStore.isConnected fun isConnected(): Boolean = receiverStatusStore.isConnected
@ -37,12 +37,12 @@ class VersionCheckerUtils @Inject constructor(
// On a new installation, set it as 30 days old in order to warn that there is a new version. // On a new installation, set it as 30 days old in order to warn that there is a new version.
sp.putLong( sp.putLong(
R.string.key_last_time_this_version_detected, R.string.key_last_time_this_version_detected,
System.currentTimeMillis() - TimeUnit.DAYS.toMillis(30) dateUtil.now() - TimeUnit.DAYS.toMillis(30)
) )
} }
// If we are good, only check once every day. // If we are good, only check once every day.
if (System.currentTimeMillis() > sp.getLong( if (dateUtil.now() > sp.getLong(
R.string.key_last_time_this_version_detected, R.string.key_last_time_this_version_detected,
0 0
) + CHECK_EVERY ) + CHECK_EVERY
@ -51,12 +51,24 @@ class VersionCheckerUtils @Inject constructor(
} }
} }
private fun checkVersion() = if (isConnected()) { private fun checkVersion() =
if (isConnected()) {
Thread { Thread {
try { try {
val definition: String = URL("https://raw.githubusercontent.com/nightscout/AndroidAPS/versions/definition.json").readText() val definition: String = URL("https://raw.githubusercontent.com/nightscout/AndroidAPS/versions/definition.json").readText()
val version: String? = AllowedVersions().findByApi(definition, Build.VERSION.SDK_INT)?.optString("supported") val version: String? = AllowedVersions().findByApi(definition, Build.VERSION.SDK_INT)?.optString("supported")
compareWithCurrentVersion(version, config.VERSION_NAME) compareWithCurrentVersion(version, config.VERSION_NAME)
// App expiration
var endDate = sp.getLong(resourceHelper.gs(R.string.key_app_expiration) + "_" + config.VERSION_NAME, 0)
AllowedVersions().findByVersion(definition, config.VERSION_NAME)?.let { expirationJson ->
AllowedVersions().endDateToMilliseconds(expirationJson.getString("endDate"))?.let { ed ->
sp.putLong(resourceHelper.gs(R.string.key_app_expiration) + "_" + config.VERSION_NAME, ed)
endDate = ed
}
}
if (endDate != 0L) onExpiredVersionDetected(config.VERSION_NAME, dateUtil.dateString(endDate))
} catch (e: IOException) { } catch (e: IOException) {
aapsLogger.error(LTag.CORE, "Github master version check error: $e") aapsLogger.error(LTag.CORE, "Github master version check error: $e")
} }
@ -98,11 +110,11 @@ class VersionCheckerUtils @Inject constructor(
private fun onOlderVersionDetected() { private fun onOlderVersionDetected() {
aapsLogger.debug(LTag.CORE, "Version newer than master. Are you developer?") aapsLogger.debug(LTag.CORE, "Version newer than master. Are you developer?")
sp.putLong(R.string.key_last_time_this_version_detected, System.currentTimeMillis()) sp.putLong(R.string.key_last_time_this_version_detected, dateUtil.now())
} }
private fun onSameVersionDetected() { private fun onSameVersionDetected() {
sp.putLong(R.string.key_last_time_this_version_detected, System.currentTimeMillis()) sp.putLong(R.string.key_last_time_this_version_detected, dateUtil.now())
} }
private fun onVersionNotDetectable() { private fun onVersionNotDetectable() {
@ -110,7 +122,7 @@ class VersionCheckerUtils @Inject constructor(
} }
private fun onNewVersionDetected(currentVersion: String, newVersion: String?) { private fun onNewVersionDetected(currentVersion: String, newVersion: String?) {
val now = System.currentTimeMillis() val now = dateUtil.now()
if (now > sp.getLong(R.string.key_last_versionchecker_warning, 0) + WARN_EVERY) { if (now > sp.getLong(R.string.key_last_versionchecker_warning, 0) + WARN_EVERY) {
aapsLogger.debug(LTag.CORE, "Version $currentVersion outdated. Found $newVersion") aapsLogger.debug(LTag.CORE, "Version $currentVersion outdated. Found $newVersion")
val notification = Notification( val notification = Notification(
@ -123,6 +135,20 @@ class VersionCheckerUtils @Inject constructor(
} }
} }
private fun onExpiredVersionDetected(currentVersion: String, endDate: String?) {
val now = dateUtil.now()
if (now > sp.getLong(R.string.key_last_expired_versionchecker_warning, 0) + WARN_EVERY) {
aapsLogger.debug(LTag.CORE, "Version $currentVersion expired.")
val notification = Notification(
Notification.VERSION_EXPIRE,
resourceHelper.gs(R.string.version_expire, currentVersion, endDate),
Notification.LOW
)
rxBus.send(EventNewNotification(notification))
sp.putLong(R.string.key_last_expired_versionchecker_warning, now)
}
}
private fun String?.toNumberList() = private fun String?.toNumberList() =
this?.numericVersionPart().takeIf { !it.isNullOrBlank() }?.split(".")?.map { it.toInt() } this?.numericVersionPart().takeIf { !it.isNullOrBlank() }?.split(".")?.map { it.toInt() }
@ -156,15 +182,3 @@ fun String.numericVersionPart(): String =
return file?.lines()?.filter { regex.matches(it) } return file?.lines()?.filter { regex.matches(it) }
?.mapNotNull { regex.matchEntire(it)?.groupValues?.getOrNull(3) }?.firstOrNull() ?.mapNotNull { regex.matchEntire(it)?.groupValues?.getOrNull(3) }?.firstOrNull()
} }
@Deprecated(
replaceWith = ReplaceWith("numericVersionPart()"),
message = "Will not work if RCs have another index number in it."
)
fun String.versionStrip() = this.mapNotNull {
when (it) {
in '0'..'9' -> it
'.' -> it
else -> null
}
}.joinToString(separator = "")

View file

@ -121,6 +121,7 @@ open class Notification {
const val UNSUPPORTED_ACTION_IN_PUMP = 71 const val UNSUPPORTED_ACTION_IN_PUMP = 71
const val WRONG_PUMP_DATA = 72 const val WRONG_PUMP_DATA = 72
const val NSCLIENT_VERSION_DOES_NOT_MATCH = 73 const val NSCLIENT_VERSION_DOES_NOT_MATCH = 73
const val VERSION_EXPIRE = 74
const val USER_MESSAGE = 1000 const val USER_MESSAGE = 1000

View file

@ -63,6 +63,7 @@
<string name="key_adult" translatable="false">adult</string> <string name="key_adult" translatable="false">adult</string>
<string name="key_resistantadult" translatable="false">resistantadult</string> <string name="key_resistantadult" translatable="false">resistantadult</string>
<string name="key_pregnant" translatable="false">pregnant</string> <string name="key_pregnant" translatable="false">pregnant</string>
<string name="key_app_expiration" translatable="false">app_expiration</string>
<!-- General--> <!-- General-->
<string name="refresh">Refresh</string> <string name="refresh">Refresh</string>
@ -374,12 +375,14 @@
<!-- VersionChecker --> <!-- VersionChecker -->
<string name="key_last_time_this_version_detected" translatable="false">last_time_this_version_detected</string> <string name="key_last_time_this_version_detected" translatable="false">last_time_this_version_detected</string>
<string name="key_last_versionchecker_warning" translatable="false">last_versionchecker_waring</string> <string name="key_last_versionchecker_warning" translatable="false">last_versionchecker_warning</string>
<string name="key_last_expired_versionchecker_warning" translatable="false">last_expired_version_checker_warning</string>
<string name="key_last_versionchecker_plugin_warning" translatable="false">last_versionchecker_plugin_waring</string> <string name="key_last_versionchecker_plugin_warning" translatable="false">last_versionchecker_plugin_waring</string>
<string name="key_last_revoked_certs_check" translatable="false">last_revoked_certs_check</string> <string name="key_last_revoked_certs_check" translatable="false">last_revoked_certs_check</string>
<string name="signature_verifier">Signature verifier</string> <string name="signature_verifier">Signature verifier</string>
<string name="running_invalid_version">We have detected that you are running an invalid version. Loop disabled!</string> <string name="running_invalid_version">We have detected that you are running an invalid version. Loop disabled!</string>
<string name="versionavailable">Version %1$s available</string> <string name="versionavailable">Version %1$s available</string>
<string name="version_expire">Version %1$s expire on %2$s</string>
<!-- Permissions --> <!-- Permissions -->
<string name="alert_dialog_storage_permission_text">Please reboot your phone or restart AndroidAPS from the System Settings \notherwise Android APS will not have logging (important to track and verify that the algorithms are working correctly)!</string> <string name="alert_dialog_storage_permission_text">Please reboot your phone or restart AndroidAPS from the System Settings \notherwise Android APS will not have logging (important to track and verify that the algorithms are working correctly)!</string>

View file

@ -5,16 +5,23 @@ import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils
import info.nightscout.androidaps.plugins.constraints.versionChecker.numericVersionPart
import info.nightscout.androidaps.receivers.ReceiverStatusStore import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyString
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
class VersionCheckerUtilsKtTest : TestBase() { @Suppress("SpellCheckingInspection") class VersionCheckerUtilsKtTest : TestBase() {
private lateinit var versionCheckerUtils: VersionCheckerUtils private lateinit var versionCheckerUtils: VersionCheckerUtils
@ -23,11 +30,11 @@ class VersionCheckerUtilsKtTest : TestBase() {
@Mock lateinit var context: Context @Mock lateinit var context: Context
@Mock lateinit var receiverStatusStore: ReceiverStatusStore @Mock lateinit var receiverStatusStore: ReceiverStatusStore
@Mock lateinit var config: Config @Mock lateinit var config: Config
@Mock lateinit var dateUtil: DateUtil
private val rxBus = RxBus(aapsSchedulers) @Mock lateinit var rxBus: RxBus
@Before fun setup() { @Before fun setup() {
versionCheckerUtils = VersionCheckerUtils(aapsLogger, sp, resourceHelper, rxBus, config, context, receiverStatusStore) versionCheckerUtils = VersionCheckerUtils(aapsLogger, sp, resourceHelper, rxBus, config, receiverStatusStore, dateUtil)
} }
@Test @Test
@ -65,7 +72,6 @@ class VersionCheckerUtilsKtTest : TestBase() {
assertArrayEquals(intArrayOf(67, 8, 31, 5), versionCheckerUtils.versionDigits("67.8.31.5.153.4.2")) assertArrayEquals(intArrayOf(67, 8, 31, 5), versionCheckerUtils.versionDigits("67.8.31.5.153.4.2"))
} }
/*
@Test @Test
fun `should keep 2 digit version`() { fun `should keep 2 digit version`() {
assertEquals("1.2", "1.2".numericVersionPart()) assertEquals("1.2", "1.2".numericVersionPart())
@ -126,7 +132,6 @@ class VersionCheckerUtilsKtTest : TestBase() {
assertEquals("1.2", "1.2.RC5".numericVersionPart()) assertEquals("1.2", "1.2.RC5".numericVersionPart())
} }
*/
@Suppress("SpellCheckingInspection") @Suppress("SpellCheckingInspection")
@Test @Test
fun findVersionMatchesRegularVersion() { fun findVersionMatchesRegularVersion() {
@ -141,7 +146,6 @@ class VersionCheckerUtilsKtTest : TestBase() {
assertEquals("2.2.2", detectedVersion) assertEquals("2.2.2", detectedVersion)
} }
/* TODO finish this tests
// In case we merge a "x.x.x-dev" into master, don't see it as update. // In case we merge a "x.x.x-dev" into master, don't see it as update.
@Test @Test
fun `should return null on non-digit versions on master`() { fun `should return null on non-digit versions on master`() {
@ -163,138 +167,55 @@ class VersionCheckerUtilsKtTest : TestBase() {
assertEquals(null, detectedVersion) assertEquals(null, detectedVersion)
} }
/*
@Test @Test
fun testVersionStrip() {
assertEquals("2.2.2", "2.2.2".versionStrip())
assertEquals("2.2.2", "2.2.2-dev".versionStrip())
assertEquals("2.2.2", "2.2.2dev".versionStrip())
assertEquals("2.2.2", """"2.2.2"""".versionStrip())
}
*/
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `should find update1`() { fun `should find update1`() {
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1") versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1")
verify(rxBus, times(1)).send(anyObject())
//verify(bus, times(1)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `should find update2`() { fun `should find update2`() {
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1-dev") versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1-dev")
verify(rxBus, times(1)).send(anyObject())
//verify(bus, times(1)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `should find update3`() { fun `should find update3`() {
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.1") versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.1")
verify(rxBus, times(1)).send(anyObject())
//verify(bus, times(1)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `should find update4`() { fun `should find update4`() {
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2", currentVersion = "2.1.1") versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2", currentVersion = "2.1.1")
verify(rxBus, times(1)).send(anyObject())
//verify(bus, times(1)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `should find update5`() { fun `should find update5`() {
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2-dev") versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2-dev")
verify(rxBus, times(1)).send(anyObject())
//verify(bus, times(1)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `should find update6`() { fun `should find update6`() {
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2dev") versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2dev")
verify(rxBus, times(1)).send(anyObject())
//verify(bus, times(1)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `should not find update on fourth version digit`() { fun `should not find update on fourth version digit`() {
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.5.0", currentVersion = "2.5.0.1") versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.5.0", currentVersion = "2.5.0.1")
verify(rxBus, times(0)).send(anyObject())
//verify(bus, times(0)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_time_this_version_detected), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `should not find update on personal version with same number`() { fun `should not find update on personal version with same number`() {
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.5.0", currentVersion = "2.5.0-myversion") versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.5.0", currentVersion = "2.5.0-myversion")
verify(rxBus, times(0)).send(anyObject())
//verify(bus, times(0)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_time_this_version_detected), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find same version`() { fun `find same version`() {
val buildGradle = """blabla val buildGradle = """blabla
| android { | android {
@ -303,18 +224,11 @@ class VersionCheckerUtilsKtTest : TestBase() {
| version = "2.2.2" | version = "2.2.2"
| appName = "Aaoeu" | appName = "Aaoeu"
""".trimMargin() """.trimMargin()
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.2.2") versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.2.2")
//verify(bus, times(0)).post(any()) verify(rxBus, times(0)).send(anyObject())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_time_this_version_detected), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version`() { fun `find higher version`() {
val buildGradle = """blabla val buildGradle = """blabla
| android { | android {
@ -323,18 +237,11 @@ class VersionCheckerUtilsKtTest : TestBase() {
| version = "3.0.0" | version = "3.0.0"
| appName = "Aaoeu" | appName = "Aaoeu"
""".trimMargin() """.trimMargin()
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.2.2") versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.2.2")
verify(rxBus, times(1)).send(anyObject())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version with longer number`() { fun `find higher version with longer number`() {
val buildGradle = """blabla val buildGradle = """blabla
| android { | android {
@ -343,18 +250,11 @@ class VersionCheckerUtilsKtTest : TestBase() {
| version = "3.0" | version = "3.0"
| appName = "Aaoeu" | appName = "Aaoeu"
""".trimMargin() """.trimMargin()
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.2.2") versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.2.2")
verify(rxBus, times(1)).send(anyObject())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version after RC`() { fun `find higher version after RC`() {
val buildGradle = """blabla val buildGradle = """blabla
| android { | android {
@ -363,18 +263,11 @@ class VersionCheckerUtilsKtTest : TestBase() {
| version = "3.0.0" | version = "3.0.0"
| appName = "Aaoeu" | appName = "Aaoeu"
""".trimMargin() """.trimMargin()
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.0-RC04") versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.0-RC04")
verify(rxBus, times(1)).send(anyObject())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version after RC 2 - typo`() { fun `find higher version after RC 2 - typo`() {
val buildGradle = """blabla val buildGradle = """blabla
| android { | android {
@ -383,18 +276,11 @@ class VersionCheckerUtilsKtTest : TestBase() {
| version = "3.0.0" | version = "3.0.0"
| appName = "Aaoeu" | appName = "Aaoeu"
""".trimMargin() """.trimMargin()
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.0RC04") versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.0RC04")
verify(rxBus, times(1)).send(anyObject())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version after RC 3 - typo`() { fun `find higher version after RC 3 - typo`() {
val buildGradle = """blabla val buildGradle = """blabla
| android { | android {
@ -403,18 +289,11 @@ class VersionCheckerUtilsKtTest : TestBase() {
| version = "3.0.0" | version = "3.0.0"
| appName = "Aaoeu" | appName = "Aaoeu"
""".trimMargin() """.trimMargin()
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.RC04") versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.RC04")
verify(rxBus, times(1)).send(anyObject())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version after RC 4 - typo`() { fun `find higher version after RC 4 - typo`() {
val buildGradle = """blabla val buildGradle = """blabla
| android { | android {
@ -423,18 +302,11 @@ class VersionCheckerUtilsKtTest : TestBase() {
| version = "3.0.0" | version = "3.0.0"
| appName = "Aaoeu" | appName = "Aaoeu"
""".trimMargin() """.trimMargin()
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.0.RC04") versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.0.RC04")
verify(rxBus, times(1)).send(anyObject())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version on multi digit numbers`() { fun `find higher version on multi digit numbers`() {
val buildGradle = """blabla val buildGradle = """blabla
| android { | android {
@ -443,18 +315,11 @@ class VersionCheckerUtilsKtTest : TestBase() {
| version = "3.7.12" | version = "3.7.12"
| appName = "Aaoeu" | appName = "Aaoeu"
""".trimMargin() """.trimMargin()
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.7.9") versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.7.9")
verify(rxBus, times(1)).send(anyObject())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `don't find higher version on higher but shorter version`() { fun `don't find higher version on higher but shorter version`() {
val buildGradle = """blabla val buildGradle = """blabla
| android { | android {
@ -463,18 +328,11 @@ class VersionCheckerUtilsKtTest : TestBase() {
| version = "2.2.2" | version = "2.2.2"
| appName = "Aaoeu" | appName = "Aaoeu"
""".trimMargin() """.trimMargin()
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.3") versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.3")
verify(rxBus, times(0)).send(anyObject())
//verify(bus, times(0)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_time_this_version_detected), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `don't find higher version if on next RC`() { fun `don't find higher version if on next RC`() {
val buildGradle = """blabla val buildGradle = """blabla
| android { | android {
@ -483,40 +341,42 @@ class VersionCheckerUtilsKtTest : TestBase() {
| version = "2.2.2" | version = "2.2.2"
| appName = "Aaoeu" | appName = "Aaoeu"
""".trimMargin() """.trimMargin()
prepareMainApp()
versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.3-RC") versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.3-RC")
verify(rxBus, times(0)).send(anyObject())
//verify(bus, times(0)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_time_this_version_detected), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
} }
@Test @Test
@PrepareForTest(System::class) fun `warn on beta`() {
val buildGradle = """blabla
| android {
| aosenuthoae
| }
| version = "2.2.2"
| appName = "Aaoeu"
""".trimMargin()
versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.2-beta1")
verify(rxBus, times(1)).send(anyObject())
}
@Test
fun `warn on rc`() {
val buildGradle = """blabla
| android {
| aosenuthoae
| }
| version = "2.2.0"
| appName = "Aaoeu"
""".trimMargin()
versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.2-rc1")
verify(rxBus, times(1)).send(anyObject())
}
@Before
fun `set time`() { fun `set time`() {
PowerMockito.spy(System::class.java) `when`(dateUtil.now()).thenReturn(10000000000L)
PowerMockito.`when`(System.currentTimeMillis()).thenReturn(100L) assertEquals(10000000000L, dateUtil.now())
assertEquals(100L, System.currentTimeMillis()) `when`(resourceHelper.gs(anyInt(), anyString())).thenReturn("")
} }
private fun prepareMainApp() {
PowerMockito.mockStatic(MainApp::class.java)
val mainApp = mock<MainApp>(MainApp::class.java)
`when`(MainApp.instance()).thenReturn(mainApp)
`when`(MainApp.gs(ArgumentMatchers.anyInt())).thenReturn("some dummy string")
prepareSP()
}
private fun prepareSP() {
PowerMockito.mockStatic(SP::class.java)
}
private fun prepareLogging() {
PowerMockito.mockStatic(L::class.java)
`when`(L.isEnabled(any())).thenReturn(true)
}
*/
} }