test: Update checker

Also fixed bug found from the test unit
This commit is contained in:
Ahmad Ansori Palembani 2024-05-22 12:24:19 +07:00
parent 466d25156b
commit 0722cb2f2d
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
5 changed files with 105 additions and 25 deletions

View file

@ -73,16 +73,12 @@ jobs:
# PROD
- name: Build release build
if: startsWith(env.VERSION_TAG, 'v')
uses: gradle/gradle-command-action@v2
with:
arguments: assembleStandardRelease
run: ./gradlew assembleStandardRelease testStandardReleaseUnitTest
# NIGHTLY
- name: Build nightly build
if: startsWith(env.VERSION_TAG, 'r')
uses: gradle/gradle-command-action@v2
with:
arguments: assembleStandardNightly
run: ./gradlew assembleStandardNightly testStandardNightlyUnitTest
- name: Sign APK
if: env.VERSION_TAG != ''

View file

@ -305,6 +305,10 @@ dependencies {
// Android Chart
implementation(libs.mpandroidchart)
// Tests
testImplementation(libs.bundles.test)
androidTestImplementation(libs.junit.android)
}
tasks {

View file

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.data.updater
import android.content.Context
import android.os.Build
import androidx.annotation.VisibleForTesting
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.network.GET
@ -11,15 +12,16 @@ import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.system.localeContext
import eu.kanade.tachiyomi.util.system.withIOContext
import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Date
import java.util.concurrent.TimeUnit
class AppUpdateChecker {
private val json: Json by injectLazy()
private val networkService: NetworkHelper by injectLazy()
private val preferences: PreferencesHelper by injectLazy()
class AppUpdateChecker(
private val json: Json = Injekt.get(),
private val networkService: NetworkHelper = Injekt.get(),
private val preferences: PreferencesHelper = Injekt.get(),
) {
suspend fun checkForUpdate(context: Context, isUserPrompt: Boolean = false, doExtrasAfterNewUpdate: Boolean = true): AppUpdateResult {
// Limit checks to once a day at most
@ -84,7 +86,8 @@ class AppUpdateChecker {
}
}
private fun isNewVersion(versionTag: String, currentVersion: String = BuildConfig.VERSION_NAME): Boolean {
@VisibleForTesting
fun isNewVersion(versionTag: String, currentVersion: String = BuildConfig.VERSION_NAME, isNightly: Boolean = BuildConfig.NIGHTLY): Boolean {
// Removes prefixes like "r" or "v"
val newVersion = versionTag.replace("[^\\d.-]".toRegex(), "")
val oldVersion = currentVersion.replace("[^\\d.-]".toRegex(), "")
@ -94,15 +97,11 @@ class AppUpdateChecker {
val isNewVersionNightly = newSemVer.size == 1
val oldSemVer = oldPreReleaseVer.first().split(".").map { it.toInt() }
// Nightly doesn't use semver
if (!BuildConfig.NIGHTLY) {
oldSemVer.mapIndexed { index, i ->
// Keeping this nightly check for backwards compat
if (!isNewVersionNightly && newSemVer.getOrElse(index) { i } > i) {
return true
} else if (newSemVer.getOrElse(index) { i } < i) {
return false
}
oldSemVer.mapIndexed { index, i ->
if (!isNewVersionNightly && !isNightly && newSemVer.getOrElse(index) { i } > i) {
return true
} else if (newSemVer.getOrElse(index) { i } < i) {
return false
}
}
// For cases of extreme patch versions (new: 1.2.3.1 vs old: 1.2.3, return true)
@ -118,12 +117,12 @@ class AppUpdateChecker {
oldPreReleaseVer.getOrNull(1)?.replace("[^\\d.-]".toRegex(), "")?.toIntOrNull()
when {
// For prod, don't bother with betas (current: 1.2.3 vs new: 1.2.3-b1)
oldPreVersion == null -> false
oldPreVersion == null && !isNightly -> false
// For betas, always use prod builds (current: 1.2.3-b1 vs new: 1.2.3)
// For nightly, don't use prod builds
newPreVersion == null -> !BuildConfig.NIGHTLY
newPreVersion == null -> !isNightly
// For nightly, higher beta ver is newer (current: 1.2.3-b1 vs new: 1.2.3-b2 or r2)
else -> (oldPreVersion < newPreVersion)
else -> (oldPreVersion ?: 0) < newPreVersion
}
}
}

View file

@ -0,0 +1,75 @@
package eu.kanade.tachiyomi.data.updater
import android.content.Context
import eu.kanade.tachiyomi.core.preference.PreferenceStore
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.network.NetworkHelper
import io.mockk.MockKAnnotations
import io.mockk.impl.annotations.MockK
import io.mockk.impl.annotations.RelaxedMockK
import io.mockk.impl.annotations.SpyK
import io.mockk.mockk
import kotlinx.serialization.json.Json
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
class AppUpdateCheckerTest {
lateinit var appUpdateChecker: AppUpdateChecker
@Before
fun setup() {
val json = mockk<Json>()
val network = mockk<NetworkHelper>()
val preferences = mockk<PreferencesHelper>()
appUpdateChecker = AppUpdateChecker(json, network, preferences)
}
@Test
fun `Check new nightly version (Tachi format)`() {
assertTrue(isNewVersion("1.2.3-r2", "1.2.3-r1", true)) // tachi format
assertTrue(isNewVersion("1.2.4-r1", "1.2.3", true)) // Unlikely to happened, but we should try anyway
}
@Test
fun `Check new nightly version (Yokai format)`() {
assertTrue(isNewVersion("r2", "1.2.3-r1", true)) // yokai format
}
@Test
fun `Nightly shouldn't get Prod build`() {
assertFalse(isNewVersion("1.2.3", "1.2.3-r2", true))
assertFalse(isNewVersion("1.2.4", "1.2.3-r2", true))
assertFalse(isNewVersion("1.2.4", "1.2.3", true))
}
@Test
fun `Beta should get Prod build`() {
assertTrue(isNewVersion("1.2.4", "1.2.3-r2", false))
assertTrue(isNewVersion("1.2.3", "1.2.3-r2", false))
}
@Test
fun `Prod should get latest Prod build`() {
assertTrue(isNewVersion("1.2.4", "1.2.3", false))
}
@Test
fun `Prod should get latest Prod build (Check for Betas)`() {
assertTrue(isNewVersion("1.2.4-r1", "1.2.3", false))
}
@Test
fun `Latest version check`() {
assertFalse(isNewVersion("1.2.3", "1.2.3", false))
assertFalse(isNewVersion("1.2.3-r1", "1.2.3-r1", false))
assertFalse(isNewVersion("1.2.3-r1", "1.2.3-r1", true))
assertFalse(isNewVersion("r1", "1.2.4-r1", true))
}
private fun isNewVersion(newVersion: String, currentVersion: String, isNightly: Boolean): Boolean {
return appUpdateChecker.isNewVersion(newVersion, currentVersion, isNightly)
}
}

View file

@ -68,7 +68,13 @@ firebase-crashlytics = { module = "com.google.firebase:firebase-crashlytics-ktx"
unifile = { module = "com.github.tachiyomiorg:unifile", version = "17bec43" }
viewstatepageradapter = { module = "com.nightlynexus.viewstatepageradapter:viewstatepageradapter", version = "1.1.0" }
viewtooltip = { module = "com.github.florent37:viewtooltip", version = "1.2.2" }
junit = { module = "junit:junit", version = "4.13.2" }
junit-android = { module = "androidx.test.ext:junit", version = "1.1.5" }
mockk = { module = "io.mockk:mockk", version = "1.13.11" }
[plugins]
kotlinter = { id = "org.jmailen.kotlinter", version = "4.1.1" }
gradle-versions = { id = "com.github.ben-manes.versions", version = "0.42.0" }
[bundles]
test = [ "junit", "mockk" ]