From f57a749c08ebd9594bd9c1fa62133db63cdc7b19 Mon Sep 17 00:00:00 2001 From: Taras Smakula <tarassmakula@gmail.com> Date: Tue, 21 Nov 2023 15:18:36 +0200 Subject: [PATCH] Move worker test to app --- app/build.gradle | 6 + .../org/futo/circles/MediaBackupWorkerTest.kt | 4 +- .../futo/circles/RefreshTokenWorkerTest.kt | 118 ++++++++++++++++++ gallery/build.gradle | 8 +- .../backup/service/MediaBackupWorker.kt | 2 +- 5 files changed, 128 insertions(+), 10 deletions(-) rename gallery/src/androidTest/java/org/futo/circles/gallery/WorkerTest.kt => app/src/androidTest/java/org/futo/circles/MediaBackupWorkerTest.kt (98%) create mode 100644 app/src/androidTest/java/org/futo/circles/RefreshTokenWorkerTest.kt diff --git a/app/build.gradle b/app/build.gradle index c7f1c027f..aabd686f9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -102,10 +102,16 @@ dependencies { implementation "com.google.dagger:hilt-android:$rootProject.ext.hilt_version" kapt "com.google.dagger:hilt-compiler:$rootProject.ext.hilt_version" + //Coroutines + def coroutines_version = '1.7.3' + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" + //test testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + androidTestImplementation "androidx.work:work-testing:2.8.1" + androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version" } kapt { diff --git a/gallery/src/androidTest/java/org/futo/circles/gallery/WorkerTest.kt b/app/src/androidTest/java/org/futo/circles/MediaBackupWorkerTest.kt similarity index 98% rename from gallery/src/androidTest/java/org/futo/circles/gallery/WorkerTest.kt rename to app/src/androidTest/java/org/futo/circles/MediaBackupWorkerTest.kt index d1b16b2b9..bdf5a6d7a 100644 --- a/gallery/src/androidTest/java/org/futo/circles/gallery/WorkerTest.kt +++ b/app/src/androidTest/java/org/futo/circles/MediaBackupWorkerTest.kt @@ -1,4 +1,4 @@ -package org.futo.circles.gallery +package org.futo.circles import android.content.Context import android.os.Handler @@ -28,7 +28,7 @@ import java.util.UUID import java.util.concurrent.TimeUnit import kotlin.coroutines.resume -class WorkerTest { +class MediaBackupWorkerTest { lateinit var context: Context diff --git a/app/src/androidTest/java/org/futo/circles/RefreshTokenWorkerTest.kt b/app/src/androidTest/java/org/futo/circles/RefreshTokenWorkerTest.kt new file mode 100644 index 000000000..65ab1dd90 --- /dev/null +++ b/app/src/androidTest/java/org/futo/circles/RefreshTokenWorkerTest.kt @@ -0,0 +1,118 @@ +package org.futo.circles + + +import android.content.Context +import android.os.Handler +import android.os.Looper +import android.util.Log +import androidx.lifecycle.Observer +import androidx.test.ext.junit.rules.ActivityScenarioRule +import androidx.test.platform.app.InstrumentationRegistry +import androidx.work.Configuration +import androidx.work.Constraints +import androidx.work.Data +import androidx.work.ExistingPeriodicWorkPolicy +import androidx.work.NetworkType +import androidx.work.PeriodicWorkRequest +import androidx.work.PeriodicWorkRequestBuilder +import androidx.work.WorkInfo +import androidx.work.WorkManager +import androidx.work.testing.SynchronousExecutor +import androidx.work.testing.WorkManagerTestInitHelper +import junit.framework.TestCase.assertTrue +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.suspendCancellableCoroutine +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest +import org.futo.circles.auth.feature.token.RefreshTokenWorker +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import java.util.UUID +import java.util.concurrent.TimeUnit +import kotlin.coroutines.resume +import kotlin.math.max + +class RefreshTokenWorkerTest { + + lateinit var context: Context + + private val job = SupervisorJob() + private val testDispatcher = StandardTestDispatcher() + private val testScope = TestScope(job + testDispatcher) + + @get:Rule + val activityRule = ActivityScenarioRule(MainActivity::class.java) + + @Before + fun setup() { + context = InstrumentationRegistry.getInstrumentation().targetContext + val config = Configuration.Builder() + .setMinimumLoggingLevel(Log.DEBUG) + .setExecutor(SynchronousExecutor()) + .build() + WorkManagerTestInitHelper.initializeTestWorkManager(context, config) + } + + @Test + fun testPeriodicWork() = testScope.runTest { + val workManager = WorkManager.getInstance(context) + val testDriver = WorkManagerTestInitHelper.getTestDriver(context) + ?: throw IllegalArgumentException("test driver is null") + + + val expireTime = 3600000L + + val sessionIdData = Data.Builder() + .putString(RefreshTokenWorker.SESSION_ID_PARAM_KEY, "test") + .build() + + val flex = max(expireTime / 3, PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS) + + val refreshRequest = PeriodicWorkRequestBuilder<RefreshTokenWorker>( + expireTime, TimeUnit.MILLISECONDS, + flex, TimeUnit.MILLISECONDS + ) + .setConstraints( + Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() + ) + .setInputData(sessionIdData) + .build() + + WorkManager.getInstance(context).enqueueUniquePeriodicWork( + "test", + ExistingPeriodicWorkPolicy.UPDATE, + refreshRequest + ).result.get() + + testDriver.setPeriodDelayMet(refreshRequest.id) + testDriver.setAllConstraintsMet(refreshRequest.id) + val isSucceeded = awaitForWork(workManager, refreshRequest.id) + assertTrue(isSucceeded) + } + + private suspend fun awaitForWork( + workManager: WorkManager, + workId: UUID + ): Boolean { + val checkWorkerLiveState = workManager.getWorkInfoByIdLiveData(workId) + + return suspendCancellableCoroutine { + val observer = object : Observer<WorkInfo> { + override fun onChanged(value: WorkInfo) { + if (value.state == WorkInfo.State.ENQUEUED) { + checkWorkerLiveState.removeObserver(this) + it.resume(true) + } + if (value.state == WorkInfo.State.FAILED || value.state == WorkInfo.State.CANCELLED) { + checkWorkerLiveState.removeObserver(this) + it.resume(false) + } + } + } + Handler(Looper.getMainLooper()).post { checkWorkerLiveState.observeForever(observer) } + } + } + +} diff --git a/gallery/build.gradle b/gallery/build.gradle index c1fb762b9..9a9613333 100644 --- a/gallery/build.gradle +++ b/gallery/build.gradle @@ -48,7 +48,7 @@ dependencies { implementation 'com.jsibbold:zoomage:1.3.1' //ExoPlayer - def exoplayer_version = '1.1.1' + def exoplayer_version = '1.2.0' implementation "androidx.media3:media3-exoplayer:$exoplayer_version" implementation "androidx.media3:media3-ui:$exoplayer_version" @@ -56,10 +56,6 @@ dependencies { def work_version = "2.8.1" implementation "androidx.work:work-runtime-ktx:$work_version" - //Coroutines - def coroutines_version = '1.7.3' - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" - //Hilt implementation "com.google.dagger:hilt-android:$rootProject.ext.hilt_version" kapt "com.google.dagger:hilt-compiler:$rootProject.ext.hilt_version" @@ -68,8 +64,6 @@ dependencies { testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - androidTestImplementation "androidx.work:work-testing:2.8.1" - androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version" } kapt { diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/backup/service/MediaBackupWorker.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/backup/service/MediaBackupWorker.kt index f04cb7b16..53189674b 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/backup/service/MediaBackupWorker.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/backup/service/MediaBackupWorker.kt @@ -29,7 +29,7 @@ class MediaBackupWorker @AssistedInject constructor( mediaBackupDataSource.startMediaBackup() syncService?.stopAnyBackgroundSync() } catch (t: Throwable) { - Result.failure() + return Result.failure() } return Result.success() } -- GitLab