Skip to content

Commit

Permalink
Rework test
Browse files Browse the repository at this point in the history
  • Loading branch information
seadowg committed Jun 10, 2024
1 parent 1d88a3b commit 8b1f171
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,118 +3,157 @@ package org.odk.collect.async
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.work.BackoffPolicy
import androidx.work.Data
import androidx.work.ListenableWorker
import androidx.work.Worker
import androidx.work.WorkerParameters
import androidx.work.testing.TestWorkerBuilder
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import java.util.concurrent.Executors
import java.util.function.Supplier

@RunWith(AndroidJUnit4::class)
class WorkerAdapterTest {
class TaskSpecWorkerTest {
private lateinit var worker: Worker
companion object {
private lateinit var spec: TaskSpec
}

@Before
fun setup() {
spec = mock()
worker = TestWorkerBuilder<TestWorker>(
worker = TestWorkerBuilder<TaskSpecWorker>(
context = ApplicationProvider.getApplicationContext(),
executor = Executors.newSingleThreadExecutor(),
inputData = Data.Builder()
.putString(TaskSpecWorker.DATA_TASK_SPEC_CLASS, TestTaskSpec::class.java.name)
.build(),
runAttemptCount = 0 // without setting this explicitly attempts in tests are counted starting from 1 instead of 0 like in production code
).build()

TestTaskSpec.reset()
}

@Test
fun `when task returns true should work succeed`() {
whenever(spec.getTask(any(), any(), any())).thenReturn(Supplier { true })

fun `when task returns true work should succeed`() {
TestTaskSpec.doReturn(true)
assertThat(worker.doWork(), `is`(ListenableWorker.Result.success()))
}

@Test
fun `when task returns false, retries if maxRetries not specified`() {
whenever(spec.getTask(any(), any(), any())).thenReturn(Supplier { false })
whenever(spec.maxRetries).thenReturn(null)

TestTaskSpec.doReturn(false)
assertThat(worker.doWork(), `is`(ListenableWorker.Result.retry()))
}

@Test
fun `when task returns false, retries if maxRetries is specified and is higher than runAttemptCount`() {
whenever(spec.getTask(any(), any(), any())).thenReturn(Supplier { false })
whenever(spec.maxRetries).thenReturn(3)
TestTaskSpec
.withMaxRetries(1)
.doReturn(false)

assertThat(worker.doWork(), `is`(ListenableWorker.Result.retry()))
}

@Test
fun `when task returns false, fails if maxRetries is specified and is equal to runAttemptCount`() {
whenever(spec.getTask(any(), any(), any())).thenReturn(Supplier { false })
whenever(spec.maxRetries).thenReturn(0)
TestTaskSpec
.withMaxRetries(0)
.doReturn(false)

assertThat(worker.doWork(), `is`(ListenableWorker.Result.failure()))
}

@Test
fun `when task returns false, fails if maxRetries is specified and is lower than runAttemptCount`() {
whenever(spec.getTask(any(), any(), any())).thenReturn(Supplier { false })
whenever(spec.maxRetries).thenReturn(0)
TestTaskSpec
.withMaxRetries(-1)
.doReturn(false)

assertThat(worker.doWork(), `is`(ListenableWorker.Result.failure()))
}

@Test
fun `when maxRetries is not specified, task called with isLastUniqueExecution true`() {
whenever(spec.maxRetries).thenReturn(null)
whenever(spec.getTask(any(), any(), any())).thenReturn(Supplier { true })
TestTaskSpec
.doReturn(false)

worker.doWork()

verify(spec).getTask(any(), any(), eq(true))
assertThat(TestTaskSpec.wasLastUniqueExecution, equalTo(true))
}

@Test
fun `when maxRetries is specified and it is higher than runAttemptCount, task called with isLastUniqueExecution false`() {
whenever(spec.maxRetries).thenReturn(3)
whenever(spec.getTask(any(), any(), any())).thenReturn(Supplier { true })
TestTaskSpec
.withMaxRetries(1)
.doReturn(false)

worker.doWork()

verify(spec).getTask(any(), any(), eq(false))
assertThat(TestTaskSpec.wasLastUniqueExecution, equalTo(false))
}

@Test
fun `when maxRetries is specified and it is equal to runAttemptCount, task called with isLastUniqueExecution true`() {
whenever(spec.maxRetries).thenReturn(0)
whenever(spec.getTask(any(), any(), any())).thenReturn(Supplier { true })
TestTaskSpec
.withMaxRetries(0)
.doReturn(false)

worker.doWork()

verify(spec).getTask(any(), any(), eq(true))
assertThat(TestTaskSpec.wasLastUniqueExecution, equalTo(true))
}

@Test
fun `when maxRetries is specified and it is lower than runAttemptCount, task called with isLastUniqueExecution true`() {
whenever(spec.maxRetries).thenReturn(0)
whenever(spec.getTask(any(), any(), any())).thenReturn(Supplier { true })
TestTaskSpec
.withMaxRetries(-1)
.doReturn(false)

worker.doWork()
assertThat(TestTaskSpec.wasLastUniqueExecution, equalTo(true))
}
}

verify(spec).getTask(any(), any(), eq(true))
class TestTaskSpec : TaskSpec {

companion object {

private var maxRetries: Int? = null
private var returnValue = true

var wasLastUniqueExecution = false
private set

fun reset() {
returnValue = true
maxRetries = null
wasLastUniqueExecution = false
}

fun doReturn(value: Boolean): Companion {
returnValue = value
return this
}

fun withMaxRetries(maxRetries: Int): Companion {
this.maxRetries = maxRetries
return this
}
}

class TestWorker(context: Context, parameters: WorkerParameters) : WorkerAdapter(spec, context, parameters)
override val maxRetries: Int? = Companion.maxRetries
override val backoffPolicy: BackoffPolicy? = null
override val backoffDelay: Long? = null

override fun getTask(
context: Context,
inputData: Map<String, String>,
isLastUniqueExecution: Boolean
): Supplier<Boolean> {
wasLastUniqueExecution = isLastUniqueExecution

return Supplier {
returnValue
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.odk.collect.android.instancemanagement.autosend

import android.app.Application
import org.odk.collect.async.network.NetworkStateProvider
import org.odk.collect.async.Scheduler
import org.odk.collect.async.network.NetworkStateProvider
import org.odk.collect.settings.SettingsProvider
import org.odk.collect.settings.enums.AutoSend
import org.odk.collect.settings.enums.StringIdEnumUtils.getAutoSend
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import org.odk.collect.async.network.NetworkStateProvider
import org.odk.collect.async.Scheduler
import org.odk.collect.async.network.NetworkStateProvider
import org.odk.collect.projects.Project
import org.odk.collect.settings.InMemSettingsProvider
import org.odk.collect.settings.enums.AutoSend
Expand Down

0 comments on commit 8b1f171

Please sign in to comment.