Skip to content
Snippets Groups Projects
Unverified Commit 323fb0f8 authored by Chilja Gossow's avatar Chilja Gossow Committed by GitHub
Browse files

Adds unit test for result worker (EXPOSUREAPP-4663) #2213

* write test for DiagnosisTestResultRetrievalPeriodicWorker

* klint

* Use TimeStamper
parent 081c464b
No related branches found
No related tags found
No related merge requests found
package de.rki.coronawarnapp.worker
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.work.WorkInfo
import androidx.work.WorkManager
import androidx.work.WorkRequest
import androidx.work.testing.TestDriver
import androidx.work.testing.WorkManagerTestInitHelper
import de.rki.coronawarnapp.playbook.Playbook
import de.rki.coronawarnapp.service.submission.SubmissionService
import de.rki.coronawarnapp.storage.LocalData
import de.rki.coronawarnapp.util.TimeAndDateExtensions.daysToMilliseconds
import de.rki.coronawarnapp.util.formatter.TestResult
import io.mockk.coEvery
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.slot
import io.mockk.unmockkAll
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.notNullValue
import org.hamcrest.MatcherAssert.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import java.util.Date
/**
* DiagnosisTestResultRetrievalPeriodicWorker test.
*/
@Ignore("FixMe:DiagnosisTestResultRetrievalPeriodicWorkerTest")
@RunWith(AndroidJUnit4::class)
class DiagnosisTestResultRetrievalPeriodicWorkerTest {
private lateinit var context: Context
private lateinit var workManager: WorkManager
private lateinit var request: WorkRequest
@MockK lateinit var playbook: Playbook
private val submissionService = SubmissionService(playbook)
// small delay because WorkManager does not run work instantly when delay is off
private val delay = 500L
@Before
fun setUp() {
LocalData.registrationToken("test token")
LocalData.isTestResultAvailableNotificationSent(false)
mockkObject(LocalData)
mockkObject(BackgroundWorkScheduler)
// do not init Test WorkManager instance again between tests
// leads to all tests instead of first one to fail
context = ApplicationProvider.getApplicationContext()
if (WorkManager.getInstance(context) !is TestDriver) {
WorkManagerTestInitHelper.initializeTestWorkManager(context)
}
workManager = WorkManager.getInstance(context)
every { BackgroundWorkScheduler["buildDiagnosisTestResultRetrievalPeriodicWork"]() } answers {
request = this.callOriginal() as WorkRequest
request
}
val slot = slot<String>()
every { BackgroundWorkScheduler["isWorkActive"](capture(slot)) } answers {
!(slot.isCaptured && slot.captured ==
BackgroundWorkScheduler.WorkTag.DIAGNOSIS_TEST_RESULT_RETRIEVAL_PERIODIC_WORKER.tag)
}
}
/**
* Test worker for running more than a set amount of days.
*
* @see [BackgroundConstants.POLLING_VALIDITY_MAX_DAYS]
*/
@Test
fun testDiagnosisTestResultRetrievalPeriodicWorkerCancel() {
val past = System.currentTimeMillis() -
(BackgroundConstants.POLLING_VALIDITY_MAX_DAYS.toLong() + 1).daysToMilliseconds()
testDiagnosisTestResultRetrievalPeriodicWorkerForResult(mockk(), past, true)
}
/**
* Test worker for running less than a set amount of days, [TestResult.PENDING].
*
* @see [BackgroundConstants.POLLING_VALIDITY_MAX_DAYS]
*/
@Test
fun testDiagnosisTestResultRetrievalPeriodicWorkerPending() {
val past = Date().time - (BackgroundConstants.POLLING_VALIDITY_MAX_DAYS.toLong() - 1).daysToMilliseconds()
testDiagnosisTestResultRetrievalPeriodicWorkerForResult(TestResult.PENDING, past)
}
/**
* Test worker for running less than a set amount of days, [TestResult.NEGATIVE] .
*
* @see [BackgroundConstants.POLLING_VALIDITY_MAX_DAYS]
*/
@Test
fun testDiagnosisTestResultRetrievalPeriodicWorkerSuccessNegative() {
val past = Date().time - (BackgroundConstants.POLLING_VALIDITY_MAX_DAYS.toLong() - 1).daysToMilliseconds()
testDiagnosisTestResultRetrievalPeriodicWorkerForResult(TestResult.NEGATIVE, past)
}
/**
* Test worker for running less than a set amount of days, [TestResult.POSITIVE] .
*
* @see [BackgroundConstants.POLLING_VALIDITY_MAX_DAYS]
*/
@Test
fun testDiagnosisTestResultRetrievalPeriodicWorkerSuccessPositive() {
val past = Date().time - (BackgroundConstants.POLLING_VALIDITY_MAX_DAYS.toLong() - 1).daysToMilliseconds()
testDiagnosisTestResultRetrievalPeriodicWorkerForResult(TestResult.POSITIVE, past)
}
/**
* Test worker for retries and fail.
*/
@Test
fun testDiagnosisTestResultRetrievalPeriodicWorkerRetryAndFail() {
val past = Date().time - (BackgroundConstants.POLLING_VALIDITY_MAX_DAYS.toLong() - 1).daysToMilliseconds()
every { LocalData.initialPollingForTestResultTimeStamp() } returns past
BackgroundWorkScheduler.startWorkScheduler()
assertThat(request, notNullValue())
var workInfo = workManager.getWorkInfoById(request.id).get()
assertThat(workInfo, notNullValue())
assertThat(workInfo.state, `is`((WorkInfo.State.ENQUEUED)))
for (i in 1..BackgroundConstants.WORKER_RETRY_COUNT_THRESHOLD + 2) {
// run job i times
runPeriodicJobInitialDelayMet()
// get job run #i result
when (i) {
BackgroundConstants.WORKER_RETRY_COUNT_THRESHOLD + 2 -> {
assertThat(request, notNullValue())
workInfo = workManager.getWorkInfoById(request.id).get()
assertThat(workInfo.runAttemptCount, `is`(0))
}
else -> {
assertThat(request, notNullValue())
workInfo = workManager.getWorkInfoById(request.id).get()
assertThat(workInfo.runAttemptCount, `is`(i))
}
}
}
}
@After
fun cleanUp() {
workManager.cancelAllWork()
unmockkAll()
}
private fun testDiagnosisTestResultRetrievalPeriodicWorkerForResult(
result: TestResult,
past: Long,
isCancelTest: Boolean = false
) {
coEvery { submissionService.asyncRequestTestResult(any()) } returns result
every { LocalData.initialPollingForTestResultTimeStamp() } returns past
BackgroundWorkScheduler.startWorkScheduler()
assertThat(request, notNullValue())
val workInfo = workManager.getWorkInfoById(request.id).get()
assertThat(workInfo, notNullValue())
assertThat(workInfo.state, `is`((WorkInfo.State.ENQUEUED)))
runPeriodicJobInitialDelayMet()
verifyTestResult(result, isCancelTest)
}
private fun verifyTestResult(result: TestResult, isCancelTest: Boolean) {
assertThat(request, notNullValue())
val workInfo = workManager.getWorkInfoById(request.id).get()
if (isCancelTest) {
assertThat(workInfo.state, `is`((WorkInfo.State.CANCELLED)))
assertThat(LocalData.isTestResultAvailableNotificationSent(), `is`(false))
} else {
when (result) {
TestResult.POSITIVE, TestResult.NEGATIVE, TestResult.INVALID -> {
assertThat(workInfo.state, `is`((WorkInfo.State.CANCELLED)))
assertThat(LocalData.isTestResultAvailableNotificationSent(), `is`(true))
}
TestResult.PENDING -> {
assertThat(workInfo.runAttemptCount, `is`(0))
assertThat(workInfo.state, `is`((WorkInfo.State.ENQUEUED)))
}
}
}
}
private fun runPeriodicJobInitialDelayMet() {
val testDriver = WorkManagerTestInitHelper.getTestDriver(context)
testDriver?.setAllConstraintsMet(request.id)
testDriver?.setInitialDelayMet(request.id)
Thread.sleep(delay)
}
}
package de.rki.coronawarnapp.task package de.rki.coronawarnapp.task
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapMerge import kotlinx.coroutines.flow.flatMapMerge
...@@ -17,14 +16,3 @@ suspend fun TaskController.submitBlocking(ourRequest: TaskRequest) = ...@@ -17,14 +16,3 @@ suspend fun TaskController.submitBlocking(ourRequest: TaskRequest) =
}.also { }.also {
Timber.v("submitBlocking(request=%s) continuing with result %s", ourRequest, it) Timber.v("submitBlocking(request=%s) continuing with result %s", ourRequest, it)
} }
suspend fun TaskController.submitAndListen(ourRequest: TaskRequest): Flow<Task.Progress> {
submit(ourRequest)
Timber.v("submitAndListen(request=%s) waiting for progress flow...", ourRequest)
return tasks.flatMapMerge { it.asFlow() }.first {
it.taskState.request.id == ourRequest.id
}.progress.also {
Timber.v("submitAndListen(request=%s) continuing with flow %s", ourRequest, it)
}
}
...@@ -14,13 +14,14 @@ import de.rki.coronawarnapp.service.submission.SubmissionService ...@@ -14,13 +14,14 @@ import de.rki.coronawarnapp.service.submission.SubmissionService
import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.storage.LocalData
import de.rki.coronawarnapp.submission.SubmissionSettings import de.rki.coronawarnapp.submission.SubmissionSettings
import de.rki.coronawarnapp.util.TimeAndDateExtensions import de.rki.coronawarnapp.util.TimeAndDateExtensions
import de.rki.coronawarnapp.util.TimeStamper
import de.rki.coronawarnapp.util.formatter.TestResult import de.rki.coronawarnapp.util.formatter.TestResult
import de.rki.coronawarnapp.util.worker.InjectedWorkerFactory import de.rki.coronawarnapp.util.worker.InjectedWorkerFactory
import de.rki.coronawarnapp.worker.BackgroundWorkScheduler.stop import de.rki.coronawarnapp.worker.BackgroundWorkScheduler.stop
import timber.log.Timber import timber.log.Timber
/** /**
* Diagnosis Test Result Periodic retrieval * Diagnosis test result retrieval by periodic polling
* *
* @see BackgroundWorkScheduler * @see BackgroundWorkScheduler
*/ */
...@@ -30,16 +31,10 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor( ...@@ -30,16 +31,10 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor(
private val testResultAvailableNotificationService: TestResultAvailableNotificationService, private val testResultAvailableNotificationService: TestResultAvailableNotificationService,
private val notificationHelper: NotificationHelper, private val notificationHelper: NotificationHelper,
private val submissionSettings: SubmissionSettings, private val submissionSettings: SubmissionSettings,
private val submissionService: SubmissionService private val submissionService: SubmissionService,
private val timeStamper: TimeStamper
) : CoroutineWorker(context, workerParams) { ) : CoroutineWorker(context, workerParams) {
/**
* If background job is running for less than 21 days, testResult is checked.
* If the job is running for more than 21 days, the job will be stopped
*
* @see LocalData.isTestResultAvailableNotificationSent
* @see LocalData.initialPollingForTestResultTimeStamp
*/
override suspend fun doWork(): Result { override suspend fun doWork(): Result {
Timber.tag(TAG).d("$id: doWork() started. Run attempt: $runAttemptCount") Timber.tag(TAG).d("$id: doWork() started. Run attempt: $runAttemptCount")
...@@ -54,7 +49,7 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor( ...@@ -54,7 +49,7 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor(
var result = Result.success() var result = Result.success()
try { try {
if (abortConditionsMet()) { if (abortConditionsMet(timeStamper.nowUTC.millis)) {
Timber.tag(TAG).d(" $id Stopping worker.") Timber.tag(TAG).d(" $id Stopping worker.")
stopWorker() stopWorker()
} else { } else {
...@@ -75,7 +70,7 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor( ...@@ -75,7 +70,7 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor(
stopWorker() stopWorker()
} }
} }
} catch (e: Exception) { } catch (ex: Exception) {
result = Result.retry() result = Result.retry()
} }
...@@ -84,7 +79,7 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor( ...@@ -84,7 +79,7 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor(
return result return result
} }
private fun abortConditionsMet(): Boolean { private fun abortConditionsMet(currentMillis: Long): Boolean {
if (LocalData.isTestResultAvailableNotificationSent()) { if (LocalData.isTestResultAvailableNotificationSent()) {
Timber.tag(TAG).d("$id: Notification already sent.") Timber.tag(TAG).d("$id: Notification already sent.")
return true return true
...@@ -96,7 +91,7 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor( ...@@ -96,7 +91,7 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor(
if (TimeAndDateExtensions.calculateDays( if (TimeAndDateExtensions.calculateDays(
LocalData.initialPollingForTestResultTimeStamp(), LocalData.initialPollingForTestResultTimeStamp(),
System.currentTimeMillis() currentMillis
) >= BackgroundConstants.POLLING_VALIDITY_MAX_DAYS ) >= BackgroundConstants.POLLING_VALIDITY_MAX_DAYS
) { ) {
Timber.tag(TAG) Timber.tag(TAG)
...@@ -118,12 +113,6 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor( ...@@ -118,12 +113,6 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor(
) )
} }
/**
* Stops the Background Polling worker
*
* @see LocalData.initialPollingForTestResultTimeStamp
* @see BackgroundWorkScheduler.stop
*/
private fun stopWorker() { private fun stopWorker() {
LocalData.initialPollingForTestResultTimeStamp(0L) LocalData.initialPollingForTestResultTimeStamp(0L)
BackgroundWorkScheduler.WorkType.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER.stop() BackgroundWorkScheduler.WorkType.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER.stop()
......
package de.rki.coronawarnapp.worker
import android.content.Context
import androidx.work.ListenableWorker
import androidx.work.Operation
import androidx.work.WorkRequest
import androidx.work.WorkerParameters
import de.rki.coronawarnapp.notification.NotificationConstants
import de.rki.coronawarnapp.notification.NotificationHelper
import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService
import de.rki.coronawarnapp.service.submission.SubmissionService
import de.rki.coronawarnapp.storage.LocalData
import de.rki.coronawarnapp.submission.SubmissionSettings
import de.rki.coronawarnapp.util.TimeAndDateExtensions.daysToMilliseconds
import de.rki.coronawarnapp.util.TimeStamper
import de.rki.coronawarnapp.util.di.AppInjector
import de.rki.coronawarnapp.util.di.ApplicationComponent
import de.rki.coronawarnapp.util.formatter.TestResult
import de.rki.coronawarnapp.util.security.EncryptedPreferencesFactory
import de.rki.coronawarnapp.util.security.EncryptionErrorResetTool
import de.rki.coronawarnapp.worker.BackgroundWorkScheduler.stop
import io.kotest.matchers.shouldBe
import io.mockk.MockKAnnotations
import io.mockk.Runs
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.impl.annotations.RelaxedMockK
import io.mockk.just
import io.mockk.mockkObject
import io.mockk.verify
import kotlinx.coroutines.test.runBlockingTest
import org.joda.time.Instant
import org.junit.Before
import org.junit.Test
import testhelpers.BaseTest
class DiagnosisTestResultRetrievalPeriodicWorkerTest : BaseTest() {
@MockK lateinit var context: Context
@MockK lateinit var request: WorkRequest
@MockK lateinit var submissionSettings: SubmissionSettings
@MockK lateinit var submissionService: SubmissionService
@MockK lateinit var testResultAvailableNotificationService: TestResultAvailableNotificationService
@MockK lateinit var notificationHelper: NotificationHelper
@MockK lateinit var appComponent: ApplicationComponent
@MockK lateinit var encryptedPreferencesFactory: EncryptedPreferencesFactory
@MockK lateinit var encryptionErrorResetTool: EncryptionErrorResetTool
@MockK lateinit var operation: Operation
@MockK lateinit var timeStamper: TimeStamper
@RelaxedMockK lateinit var workerParams: WorkerParameters
private val currentInstant = Instant.ofEpochSecond(1611764225)
private val registrationToken = "test token"
@Before
fun setUp() {
MockKAnnotations.init(this)
every { submissionSettings.hasViewedTestResult.value } returns false
every { timeStamper.nowUTC } returns currentInstant
mockkObject(AppInjector)
every { AppInjector.component } returns appComponent
every { appComponent.encryptedPreferencesFactory } returns encryptedPreferencesFactory
every { appComponent.errorResetTool } returns encryptionErrorResetTool
mockkObject(LocalData)
every { LocalData.registrationToken() } returns registrationToken
every { LocalData.isTestResultAvailableNotificationSent() } returns false
every { LocalData.initialPollingForTestResultTimeStamp() } returns currentInstant.millis
every { LocalData.initialPollingForTestResultTimeStamp(any()) } just Runs
every { LocalData.isTestResultAvailableNotificationSent(any()) } just Runs
mockkObject(BackgroundWorkScheduler)
every { BackgroundWorkScheduler.WorkType.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER.stop() } returns operation
}
@Test
fun testStopWorkerWhenResultHasBeenViewed() {
runBlockingTest {
every { submissionSettings.hasViewedTestResult.value } returns true
val worker = createWorker()
val result = worker.doWork()
coVerify(exactly = 0) { submissionService.asyncRequestTestResult(any()) }
verify(exactly = 1) { BackgroundWorkScheduler.WorkType.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER.stop() }
assert(result is ListenableWorker.Result.Success)
}
}
@Test
fun testStopWorkerWhenNotificationSent() {
runBlockingTest {
every { LocalData.isTestResultAvailableNotificationSent() } returns true
val worker = createWorker()
val result = worker.doWork()
coVerify(exactly = 0) { submissionService.asyncRequestTestResult(any()) }
verify(exactly = 1) { BackgroundWorkScheduler.WorkType.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER.stop() }
assert(result is ListenableWorker.Result.Success)
}
}
@Test
fun testStopWorkerWhenMaxDaysExceeded() {
runBlockingTest {
val past =
currentInstant - (BackgroundConstants.POLLING_VALIDITY_MAX_DAYS.toLong() + 1).daysToMilliseconds()
every { LocalData.initialPollingForTestResultTimeStamp() } returns past.millis
val worker = createWorker()
val result = worker.doWork()
coVerify(exactly = 0) { submissionService.asyncRequestTestResult(any()) }
verify(exactly = 1) { BackgroundWorkScheduler.WorkType.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER.stop() }
result shouldBe ListenableWorker.Result.success()
}
}
@Test
fun testSendNotificationWhenPositive() {
runBlockingTest {
val testResult = TestResult.POSITIVE
coEvery { submissionService.asyncRequestTestResult(registrationToken) } returns testResult
coEvery { testResultAvailableNotificationService.showTestResultAvailableNotification(testResult) } just Runs
coEvery {
notificationHelper.cancelCurrentNotification(
NotificationConstants.NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID
)
} just Runs
val worker = createWorker()
val result = worker.doWork()
coVerify { submissionService.asyncRequestTestResult(registrationToken) }
coVerify { LocalData.isTestResultAvailableNotificationSent(true) }
coVerify { testResultAvailableNotificationService.showTestResultAvailableNotification(testResult) }
coVerify {
notificationHelper.cancelCurrentNotification(
NotificationConstants.NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID
)
}
assert(result is ListenableWorker.Result.Success)
}
}
@Test
fun testSendNotificationWhenNegative() {
runBlockingTest {
val testResult = TestResult.NEGATIVE
coEvery { submissionService.asyncRequestTestResult(registrationToken) } returns testResult
coEvery { testResultAvailableNotificationService.showTestResultAvailableNotification(testResult) } just Runs
coEvery {
notificationHelper.cancelCurrentNotification(
NotificationConstants.NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID
)
} just Runs
val worker = createWorker()
val result = worker.doWork()
coVerify { submissionService.asyncRequestTestResult(registrationToken) }
coVerify { LocalData.isTestResultAvailableNotificationSent(true) }
coVerify { testResultAvailableNotificationService.showTestResultAvailableNotification(testResult) }
coVerify {
notificationHelper.cancelCurrentNotification(
NotificationConstants.NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID
)
}
assert(result is ListenableWorker.Result.Success)
}
}
@Test
fun testSendNotificationWhenInvalid() {
runBlockingTest {
val testResult = TestResult.INVALID
coEvery { submissionService.asyncRequestTestResult(registrationToken) } returns testResult
coEvery { testResultAvailableNotificationService.showTestResultAvailableNotification(testResult) } just Runs
coEvery {
notificationHelper.cancelCurrentNotification(
NotificationConstants.NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID
)
} just Runs
val worker = createWorker()
val result = worker.doWork()
coVerify { submissionService.asyncRequestTestResult(registrationToken) }
coVerify { LocalData.isTestResultAvailableNotificationSent(true) }
coVerify { testResultAvailableNotificationService.showTestResultAvailableNotification(testResult) }
coVerify {
notificationHelper.cancelCurrentNotification(
NotificationConstants.NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID
)
}
assert(result is ListenableWorker.Result.Success)
}
}
@Test
fun testSendNoNotificationWhenPending() {
runBlockingTest {
val testResult = TestResult.PENDING
coEvery { submissionService.asyncRequestTestResult(registrationToken) } returns testResult
coEvery { testResultAvailableNotificationService.showTestResultAvailableNotification(testResult) } just Runs
coEvery {
notificationHelper.cancelCurrentNotification(
NotificationConstants.NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID
)
} just Runs
val worker = createWorker()
val result = worker.doWork()
coVerify { submissionService.asyncRequestTestResult(registrationToken) }
coVerify(exactly = 0) { LocalData.isTestResultAvailableNotificationSent(true) }
coVerify(exactly = 0) {
testResultAvailableNotificationService.showTestResultAvailableNotification(
testResult
)
}
coVerify(exactly = 0) {
notificationHelper.cancelCurrentNotification(
NotificationConstants.NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID
)
}
coVerify(exactly = 0) { BackgroundWorkScheduler.WorkType.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER.stop() }
assert(result is ListenableWorker.Result.Success)
}
}
@Test
fun testRetryWhenExceptionIsThrown() {
runBlockingTest {
coEvery { submissionService.asyncRequestTestResult(registrationToken) } throws Exception()
val worker = createWorker()
val result = worker.doWork()
coVerify(exactly = 1) { submissionService.asyncRequestTestResult(any()) }
coVerify(exactly = 0) { BackgroundWorkScheduler.WorkType.DIAGNOSIS_TEST_RESULT_PERIODIC_WORKER.stop() }
result shouldBe ListenableWorker.Result.retry()
}
}
private fun createWorker() = DiagnosisTestResultRetrievalPeriodicWorker(
context,
workerParams,
testResultAvailableNotificationService,
notificationHelper,
submissionSettings,
submissionService,
timeStamper
)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment