diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/VersionCheckerPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/VersionCheckerPlugin.kt index 80daf5404f..2f38a3152f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/VersionCheckerPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/VersionCheckerPlugin.kt @@ -3,15 +3,12 @@ package info.nightscout.androidaps.plugins.constraints.versionChecker import dagger.android.HasAndroidInjector import info.nightscout.androidaps.BuildConfig import info.nightscout.androidaps.R -import info.nightscout.androidaps.interfaces.Constraint -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.interfaces.* import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification 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.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP @@ -27,13 +24,16 @@ class VersionCheckerPlugin @Inject constructor( resourceHelper: ResourceHelper, private val versionCheckerUtils: VersionCheckerUtils, val rxBus: RxBus, - aapsLogger: AAPSLogger -) : PluginBase(PluginDescription() - .mainType(PluginType.CONSTRAINTS) - .neverVisible(true) - .alwaysEnabled(true) - .showInList(false) - .pluginName(R.string.versionChecker), + aapsLogger: AAPSLogger, + private val config: Config, + private val dateUtil: DateUtil +) : PluginBase( + PluginDescription() + .mainType(PluginType.CONSTRAINTS) + .neverVisible(true) + .alwaysEnabled(true) + .showInList(false) + .pluginName(R.string.versionChecker), aapsLogger, resourceHelper, injector ), Constraints { @@ -50,6 +50,7 @@ class VersionCheckerPlugin @Inject constructor( } companion object { + private val WARN_EVERY: Long get() = TimeUnit.DAYS.toMillis(1) } @@ -57,10 +58,12 @@ class VersionCheckerPlugin @Inject constructor( override fun isClosedLoopAllowed(value: Constraint): Constraint { checkWarning() versionCheckerUtils.triggerCheckVersion() - return if (isOldVersion(gracePeriod.veryOld.daysToMillis())) - value.set(aapsLogger,false, resourceHelper.gs(R.string.very_old_version), this) - else - value + if (isOldVersion(gracePeriod.veryOld.daysToMillis())) + value[aapsLogger, false, resourceHelper.gs(R.string.very_old_version)] = this + 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) + value[aapsLogger, false, resourceHelper.gs(R.string.application_expired)] = this + return value } private fun checkWarning() { @@ -77,7 +80,8 @@ class VersionCheckerPlugin @Inject constructor( sp.putLong(R.string.key_last_versionchecker_plugin_warning, now) //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(), gracePeriod.old, gracePeriod.veryOld @@ -85,6 +89,16 @@ class VersionCheckerPlugin @Inject constructor( val notification = Notification(Notification.OLD_VERSION, message, Notification.NORMAL) 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) = diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c29ed184a8..d9c300b0f4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -902,6 +902,7 @@ old version very old version + Application expired New version for at least %1$d days available! Fallback to LGS after %2$d days, loop will be disabled after %3$d days 2h diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersionsTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersionsTest.kt index d472f0ebc2..7c5706b7ca 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersionsTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersionsTest.kt @@ -1,5 +1,8 @@ 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.Test @@ -17,4 +20,24 @@ class AllowedVersionsTest { assertEquals("2.8.2", AllowedVersions().findByApi(definition, 27)?.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")) + } } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersions.kt b/core/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersions.kt index ae320cf929..6d6c1e945a 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersions.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersions.kt @@ -1,13 +1,16 @@ package info.nightscout.androidaps.plugins.constraints.versionChecker +import org.joda.time.LocalDate import org.json.JSONArray import org.json.JSONException import org.json.JSONObject +import java.lang.Exception class AllowedVersions { fun generateSupportedVersions(): String = JSONArray() + // Android API versions .put(JSONObject().apply { put("minAndroid", 1) // 1.0 put("maxAndroid", 23) // 6.0.1 @@ -27,6 +30,15 @@ class AllowedVersions { put("maxAndroid", 99) 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() fun findByApi(definition: String?, api: Int): JSONObject? { @@ -35,11 +47,34 @@ class AllowedVersions { val array = JSONArray(definition) for (i in 0 until array.length()) { val record = array[i] as JSONObject - if (api in record.getInt("minAndroid")..record.getInt("maxAndroid")) return record + if (record.has("minAndroid") && record.has("maxAndroid")) + if (api in record.getInt("minAndroid")..record.getInt("maxAndroid")) return record } } catch (e: JSONException) { } 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 + } } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/VersionCheckerUtils.kt b/core/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/VersionCheckerUtils.kt index e8cb37aaa7..da7a41ce28 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/VersionCheckerUtils.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/VersionCheckerUtils.kt @@ -1,6 +1,5 @@ package info.nightscout.androidaps.plugins.constraints.versionChecker -import android.content.Context import android.os.Build import info.nightscout.androidaps.core.R 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.notifications.Notification import info.nightscout.androidaps.receivers.ReceiverStatusStore +import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP import java.io.IOException @@ -20,13 +20,13 @@ import javax.inject.Singleton @Singleton class VersionCheckerUtils @Inject constructor( - val aapsLogger: AAPSLogger, - val sp: SP, - val resourceHelper: ResourceHelper, - val rxBus: RxBus, + private val aapsLogger: AAPSLogger, + private val sp: SP, + private val resourceHelper: ResourceHelper, + private val rxBus: RxBus, private val config: Config, - val context: Context, - val receiverStatusStore: ReceiverStatusStore + private val receiverStatusStore: ReceiverStatusStore, + private val dateUtil: DateUtil ) { 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. sp.putLong( 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 (System.currentTimeMillis() > sp.getLong( + if (dateUtil.now() > sp.getLong( R.string.key_last_time_this_version_detected, 0 ) + CHECK_EVERY @@ -51,18 +51,30 @@ class VersionCheckerUtils @Inject constructor( } } - private fun checkVersion() = if (isConnected()) { - Thread { - try { - 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") - compareWithCurrentVersion(version, config.VERSION_NAME) - } catch (e: IOException) { - aapsLogger.error(LTag.CORE, "Github master version check error: $e") - } - }.start() - } else - aapsLogger.debug(LTag.CORE, "Github master version not checked. No connectivity") + private fun checkVersion() = + if (isConnected()) { + Thread { + try { + 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") + 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) { + aapsLogger.error(LTag.CORE, "Github master version check error: $e") + } + }.start() + } else + aapsLogger.debug(LTag.CORE, "Github master version not checked. No connectivity") @Suppress("SameParameterValue") fun compareWithCurrentVersion(newVersion: String?, currentVersion: String) { @@ -87,8 +99,8 @@ class VersionCheckerUtils @Inject constructor( (newElem - currElem).let { when { - it > 0 -> return onNewVersionDetected(currentVersion, newVersion) - it < 0 -> return onOlderVersionDetected() + it > 0 -> return onNewVersionDetected(currentVersion, newVersion) + it < 0 -> return onOlderVersionDetected() it == 0 -> Unit } } @@ -98,11 +110,11 @@ class VersionCheckerUtils @Inject constructor( private fun onOlderVersionDetected() { 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() { - 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() { @@ -110,7 +122,7 @@ class VersionCheckerUtils @Inject constructor( } 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) { aapsLogger.debug(LTag.CORE, "Version $currentVersion outdated. Found $newVersion") 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() = this?.numericVersionPart().takeIf { !it.isNullOrBlank() }?.split(".")?.map { it.toInt() } @@ -156,15 +182,3 @@ fun String.numericVersionPart(): String = return file?.lines()?.filter { regex.matches(it) } ?.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 = "") \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.kt index 3f3248ea40..b7325e964e 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.kt @@ -121,6 +121,7 @@ open class Notification { const val UNSUPPORTED_ACTION_IN_PUMP = 71 const val WRONG_PUMP_DATA = 72 const val NSCLIENT_VERSION_DOES_NOT_MATCH = 73 + const val VERSION_EXPIRE = 74 const val USER_MESSAGE = 1000 diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 8e66f84755..ae7d3d6271 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -63,6 +63,7 @@ adult resistantadult pregnant + app_expiration Refresh @@ -374,12 +375,14 @@ last_time_this_version_detected - last_versionchecker_waring + last_versionchecker_warning + last_expired_version_checker_warning last_versionchecker_plugin_waring last_revoked_certs_check Signature verifier We have detected that you are running an invalid version. Loop disabled! Version %1$s available + Version %1$s expire on %2$s 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)! diff --git a/core/src/test/java/info/nightscout/androidaps/plugins/contraints/versionChecker/VersionCheckerUtilsKtTest.kt b/core/src/test/java/info/nightscout/androidaps/plugins/contraints/versionChecker/VersionCheckerUtilsKtTest.kt index 3b617231d0..6f20a5d43e 100644 --- a/core/src/test/java/info/nightscout/androidaps/plugins/contraints/versionChecker/VersionCheckerUtilsKtTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/plugins/contraints/versionChecker/VersionCheckerUtilsKtTest.kt @@ -5,16 +5,23 @@ import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.plugins.bus.RxBus 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.utils.DateUtil import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test +import org.mockito.ArgumentMatchers.anyInt 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 @@ -23,11 +30,11 @@ class VersionCheckerUtilsKtTest : TestBase() { @Mock lateinit var context: Context @Mock lateinit var receiverStatusStore: ReceiverStatusStore @Mock lateinit var config: Config - - private val rxBus = RxBus(aapsSchedulers) + @Mock lateinit var dateUtil: DateUtil + @Mock lateinit var rxBus: RxBus @Before fun setup() { - versionCheckerUtils = VersionCheckerUtils(aapsLogger, sp, resourceHelper, rxBus, config, context, receiverStatusStore) + versionCheckerUtils = VersionCheckerUtils(aapsLogger, sp, resourceHelper, rxBus, config, receiverStatusStore, dateUtil) } @Test @@ -65,68 +72,66 @@ class VersionCheckerUtilsKtTest : TestBase() { assertArrayEquals(intArrayOf(67, 8, 31, 5), versionCheckerUtils.versionDigits("67.8.31.5.153.4.2")) } - /* - @Test - fun `should keep 2 digit version`() { - assertEquals("1.2", "1.2".numericVersionPart()) - } + @Test + fun `should keep 2 digit version`() { + assertEquals("1.2", "1.2".numericVersionPart()) + } - @Test - fun `should keep 3 digit version`() { - assertEquals("1.2.3", "1.2.3".numericVersionPart()) - } + @Test + fun `should keep 3 digit version`() { + assertEquals("1.2.3", "1.2.3".numericVersionPart()) + } - @Test - fun `should keep 4 digit version`() { - assertEquals("1.2.3.4", "1.2.3.4".numericVersionPart()) - } + @Test + fun `should keep 4 digit version`() { + assertEquals("1.2.3.4", "1.2.3.4".numericVersionPart()) + } - @Test - fun `should strip 2 digit version RC`() { - assertEquals("1.2", "1.2-RC1".numericVersionPart()) - } + @Test + fun `should strip 2 digit version RC`() { + assertEquals("1.2", "1.2-RC1".numericVersionPart()) + } - @Test - fun `should strip 2 digit version RC old format`() { - assertEquals("1.2", "1.2RC1".numericVersionPart()) - } + @Test + fun `should strip 2 digit version RC old format`() { + assertEquals("1.2", "1.2RC1".numericVersionPart()) + } - @Test - fun `should strip 2 digit version RC without digit`() { - assertEquals("1.2", "1.2-RC".numericVersionPart()) - } + @Test + fun `should strip 2 digit version RC without digit`() { + assertEquals("1.2", "1.2-RC".numericVersionPart()) + } - @Test - fun `should strip 2 digit version dev`() { - assertEquals("1.2", "1.2-dev".numericVersionPart()) - } + @Test + fun `should strip 2 digit version dev`() { + assertEquals("1.2", "1.2-dev".numericVersionPart()) + } - @Test - fun `should strip 2 digit version dev old format 1`() { - assertEquals("1.2", "1.2dev".numericVersionPart()) - } + @Test + fun `should strip 2 digit version dev old format 1`() { + assertEquals("1.2", "1.2dev".numericVersionPart()) + } - @Test - fun `should strip 2 digit version dev old format 2`() { - assertEquals("1.2", "1.2dev-a3".numericVersionPart()) - } + @Test + fun `should strip 2 digit version dev old format 2`() { + assertEquals("1.2", "1.2dev-a3".numericVersionPart()) + } - @Test - fun `should strip 3 digit version RC`() { - assertEquals("1.2.3", "1.2.3-RC1".numericVersionPart()) - } + @Test + fun `should strip 3 digit version RC`() { + assertEquals("1.2.3", "1.2.3-RC1".numericVersionPart()) + } - @Test - fun `should strip 4 digit version RC`() { - assertEquals("1.2.3.4", "1.2.3.4-RC5".numericVersionPart()) - } + @Test + fun `should strip 4 digit version RC`() { + assertEquals("1.2.3.4", "1.2.3.4-RC5".numericVersionPart()) + } - @Test - fun `should strip even with dot`() { - assertEquals("1.2", "1.2.RC5".numericVersionPart()) - } + @Test + fun `should strip even with dot`() { + assertEquals("1.2", "1.2.RC5".numericVersionPart()) + } - */ @Suppress("SpellCheckingInspection") @Test fun findVersionMatchesRegularVersion() { @@ -141,7 +146,6 @@ class VersionCheckerUtilsKtTest : TestBase() { 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. @Test fun `should return null on non-digit versions on master`() { @@ -163,138 +167,55 @@ class VersionCheckerUtilsKtTest : TestBase() { assertEquals(null, detectedVersion) } - /* - @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`() { - prepareMainApp() - versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1") - - //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) - + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update2`() { - prepareMainApp() - versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1-dev") - - //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) + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update3`() { - prepareMainApp() - versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.1") - - //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) + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update4`() { - prepareMainApp() - versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2", currentVersion = "2.1.1") - - //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) + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update5`() { - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2-dev") - - //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) + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update6`() { - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2dev") - - //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) + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `should not find update on fourth version digit`() { - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.5.0", currentVersion = "2.5.0.1") - - //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) + verify(rxBus, times(0)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `should not find update on personal version with same number`() { - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(newVersion = "2.5.0", currentVersion = "2.5.0-myversion") - - //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) + verify(rxBus, times(0)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `find same version`() { val buildGradle = """blabla | android { @@ -303,18 +224,11 @@ class VersionCheckerUtilsKtTest : TestBase() { | version = "2.2.2" | appName = "Aaoeu" """.trimMargin() - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.2.2") - //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) + verify(rxBus, times(0)).send(anyObject()) } - @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `find higher version`() { val buildGradle = """blabla | android { @@ -323,18 +237,11 @@ class VersionCheckerUtilsKtTest : TestBase() { | version = "3.0.0" | appName = "Aaoeu" """.trimMargin() - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.2.2") - - 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) + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `find higher version with longer number`() { val buildGradle = """blabla | android { @@ -343,18 +250,11 @@ class VersionCheckerUtilsKtTest : TestBase() { | version = "3.0" | appName = "Aaoeu" """.trimMargin() - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.2.2") - - 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) + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `find higher version after RC`() { val buildGradle = """blabla | android { @@ -363,18 +263,11 @@ class VersionCheckerUtilsKtTest : TestBase() { | version = "3.0.0" | appName = "Aaoeu" """.trimMargin() - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.0-RC04") - - 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) + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `find higher version after RC 2 - typo`() { val buildGradle = """blabla | android { @@ -383,18 +276,11 @@ class VersionCheckerUtilsKtTest : TestBase() { | version = "3.0.0" | appName = "Aaoeu" """.trimMargin() - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.0RC04") - - 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) + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `find higher version after RC 3 - typo`() { val buildGradle = """blabla | android { @@ -403,18 +289,11 @@ class VersionCheckerUtilsKtTest : TestBase() { | version = "3.0.0" | appName = "Aaoeu" """.trimMargin() - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.RC04") - - 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) + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `find higher version after RC 4 - typo`() { val buildGradle = """blabla | android { @@ -423,18 +302,11 @@ class VersionCheckerUtilsKtTest : TestBase() { | version = "3.0.0" | appName = "Aaoeu" """.trimMargin() - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.0.RC04") - - 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) + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `find higher version on multi digit numbers`() { val buildGradle = """blabla | android { @@ -443,18 +315,11 @@ class VersionCheckerUtilsKtTest : TestBase() { | version = "3.7.12" | appName = "Aaoeu" """.trimMargin() - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "3.7.9") - - 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) + verify(rxBus, times(1)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `don't find higher version on higher but shorter version`() { val buildGradle = """blabla | android { @@ -463,18 +328,11 @@ class VersionCheckerUtilsKtTest : TestBase() { | version = "2.2.2" | appName = "Aaoeu" """.trimMargin() - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.3") - - //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) + verify(rxBus, times(0)).send(anyObject()) } @Test - @PrepareForTest(MainApp::class, L::class, SP::class) fun `don't find higher version if on next RC`() { val buildGradle = """blabla | android { @@ -483,40 +341,42 @@ class VersionCheckerUtilsKtTest : TestBase() { | version = "2.2.2" | appName = "Aaoeu" """.trimMargin() - prepareMainApp() versionCheckerUtils.compareWithCurrentVersion(versionCheckerUtils.findVersion(buildGradle), currentVersion = "2.3-RC") - - //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) + verify(rxBus, times(0)).send(anyObject()) } - @Test - @PrepareForTest(System::class) + @Test + 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`() { - PowerMockito.spy(System::class.java) - PowerMockito.`when`(System.currentTimeMillis()).thenReturn(100L) + `when`(dateUtil.now()).thenReturn(10000000000L) + 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::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) - } - */ }