| 1 |
package io.oxygenhub.android.ui |
| 2 |
|
| 3 |
import io.oxygenhub.android.FakeHubApi |
| 4 |
import io.oxygenhub.android.MainDispatcherRule |
| 5 |
import io.oxygenhub.android.api.FlowJob |
| 6 |
import io.oxygenhub.android.api.FlowRun |
| 7 |
import io.oxygenhub.android.api.LogLine |
| 8 |
import io.oxygenhub.android.ui.common.Load |
| 9 |
import io.oxygenhub.android.ui.flow.JobLogViewModel |
| 10 |
import io.oxygenhub.android.ui.flow.RunViewModel |
| 11 |
import io.oxygenhub.android.ui.flow.RunsViewModel |
| 12 |
import kotlinx.coroutines.test.runTest |
| 13 |
import org.junit.Assert.assertEquals |
| 14 |
import org.junit.Assert.assertFalse |
| 15 |
import org.junit.Assert.assertTrue |
| 16 |
import org.junit.Rule |
| 17 |
import org.junit.Test |
| 18 |
|
| 19 |
class FlowViewModelsTest { |
| 20 |
@get:Rule val main = MainDispatcherRule() |
| 21 |
|
| 22 |
private val api = FakeHubApi().apply { |
| 23 |
runList = listOf(FlowRun(56, "main", "passed"), FlowRun(55, "main", "failed")) |
| 24 |
runStore[56] = FlowRun(56, "main", "running", jobs = listOf(FlowJob("count", "running", runner = "android-pixel-10-pro-fold"))) |
| 25 |
logs["count"] = mutableListOf(LogLine(1, 0, "flow", "fetching"), LogLine(2, 1800, "stdout", "step 1 of 120")) |
| 26 |
} |
| 27 |
|
| 28 |
@Test |
| 29 |
fun listsTheRepositorysRuns() { |
| 30 |
val runs = (RunsViewModel(api, "andymccall", "phone-runner-demo").state.value as Load.Ready).value |
| 31 |
assertEquals(listOf(56L, 55L), runs.map { it.number }) |
| 32 |
} |
| 33 |
|
| 34 |
@Test |
| 35 |
fun aRunFollowsItsJobsAndCanBeCancelled() = runTest { |
| 36 |
val vm = RunViewModel(api, "andymccall", "phone-runner-demo", 56, pollMs = 0) |
| 37 |
assertTrue((vm.state.value as Load.Ready).value.live) |
| 38 |
api.runStore[56] = api.runStore.getValue(56).copy(status = "passed", jobs = listOf(FlowJob("count", "passed", runner = "plex-1"))) |
| 39 |
vm.poll() |
| 40 |
assertEquals("plex-1", (vm.state.value as Load.Ready).value.jobs[0].runner) |
| 41 |
vm.cancel() |
| 42 |
assertTrue("cancel 56" in api.calls) |
| 43 |
vm.rerunJob("count") |
| 44 |
assertTrue("rerun 56 count" in api.calls) |
| 45 |
} |
| 46 |
|
| 47 |
@Test |
| 48 |
fun aGatedJobIsApprovedOrRejectedAndARunExpedited() = runTest { |
| 49 |
val vm = RunViewModel(api, "andymccall", "phone-runner-demo", 56, pollMs = 0) |
| 50 |
vm.decide("deploy", approve = true) |
| 51 |
vm.decide("deploy", approve = false) |
| 52 |
vm.expedite(" the fix for the outage ") |
| 53 |
assertEquals(listOf("approve 56 deploy", "reject 56 deploy", "expedite 56 the fix for the outage"), api.calls.filter { it.startsWith("approve") || it.startsWith("reject") || it.startsWith("expedite") }) |
| 54 |
val gated = io.oxygenhub.android.api.FlowJob("deploy", status = "queued", approval = "waiting") |
| 55 |
assertTrue(gated.waitsForPerson) |
| 56 |
assertTrue(!gated.copy(approval = "approved").waitsForPerson && !gated.copy(status = "running").waitsForPerson) |
| 57 |
} |
| 58 |
|
| 59 |
@Test |
| 60 |
fun aLogGrowsFromTheLastLineHeldUntilTheJobEnds() = runTest { |
| 61 |
val vm = JobLogViewModel(api, "andymccall", "phone-runner-demo", 56, "count", pollMs = 0) |
| 62 |
var log = (vm.state.value as Load.Ready).value |
| 63 |
assertEquals(listOf("fetching", "step 1 of 120"), log.lines.map { it.text }) |
| 64 |
assertTrue(log.live) |
| 65 |
api.logs.getValue("count") += LogLine(3, 2500, "flow", "── handed back by android-pixel-10-pro-fold: off Wi-Fi") |
| 66 |
api.runStore[56] = api.runStore.getValue(56).copy(status = "running", jobs = listOf(FlowJob("count", "queued"))) |
| 67 |
vm.next() |
| 68 |
log = (vm.state.value as Load.Ready).value |
| 69 |
assertEquals(3, log.lines.size) |
| 70 |
assertTrue("log count after 2" in api.calls) |
| 71 |
api.runStore[56] = api.runStore.getValue(56).copy(status = "passed", jobs = listOf(FlowJob("count", "passed"))) |
| 72 |
vm.next() |
| 73 |
assertFalse((vm.state.value as Load.Ready).value.live) |
| 74 |
assertEquals("passed", (vm.state.value as Load.Ready).value.status) |
| 75 |
} |
| 76 |
} |