| 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.HubException |
| 8 |
import io.oxygenhub.android.api.StarterAssistant |
| 9 |
import io.oxygenhub.android.api.StarterStatus |
| 10 |
import io.oxygenhub.android.api.UserFlowRun |
| 11 |
import io.oxygenhub.android.api.Visibility |
| 12 |
import io.oxygenhub.android.ui.flow.RunFilter |
| 13 |
import io.oxygenhub.android.ui.flow.filtered |
| 14 |
import io.oxygenhub.android.ui.flow.runSky |
| 15 |
import io.oxygenhub.android.ui.flow.took |
| 16 |
import io.oxygenhub.android.ui.repos.Making |
| 17 |
import io.oxygenhub.android.ui.repos.NewRepositoryViewModel |
| 18 |
import org.junit.Assert.assertEquals |
| 19 |
import org.junit.Assert.assertTrue |
| 20 |
import org.junit.Rule |
| 21 |
import org.junit.Test |
| 22 |
|
| 23 |
class NewRepositoryAndFlowTest { |
| 24 |
@get:Rule val main = MainDispatcherRule() |
| 25 |
|
| 26 |
private val api = FakeHubApi() |
| 27 |
|
| 28 |
@Test |
| 29 |
fun aRepositoryIsMadeUnderYouOrAnOrganisationYouBelongTo() { |
| 30 |
val vm = NewRepositoryViewModel(api, "andymccall") |
| 31 |
assertEquals(listOf("andymccall", "doomsdayone"), vm.owners.value) |
| 32 |
vm.create("doomsdayone", " pong ", " A game ", Visibility.Private, ask = "") |
| 33 |
val done = vm.making.value as Making.Done |
| 34 |
assertEquals(("doomsdayone" to "pong"), done.repo.owner to done.repo.name) |
| 35 |
assertEquals(Visibility.Private, done.repo.visibility) |
| 36 |
assertTrue("no starter without an assistant: ${api.calls}", api.calls.none { it.startsWith("start starter") }) |
| 37 |
} |
| 38 |
|
| 39 |
@Test |
| 40 |
fun anAssistantDraftsTheStarterAndTheScreenFollowsIt() { |
| 41 |
api.starterAssistants = { listOf(StarterAssistant("Helper", "m1", "the site")) } |
| 42 |
api.starterStatuses = mutableListOf(StarterStatus("running", "Helper"), StarterStatus("done", "Helper", "abc", listOf("README.md", "src/main.rs"))) |
| 43 |
val vm = NewRepositoryViewModel(api, "andymccall", pollMs = 10) |
| 44 |
vm.create("andymccall", "pong", "", Visibility.Public, ask = "A pong game in Rust") |
| 45 |
assertTrue(vm.making.value is Making.Drafting) |
| 46 |
main.dispatcher.scheduler.advanceUntilIdle() |
| 47 |
val done = vm.making.value as Making.Done |
| 48 |
assertEquals(listOf("README.md", "src/main.rs"), done.files) |
| 49 |
assertEquals("Helper", done.assistant) |
| 50 |
} |
| 51 |
|
| 52 |
@Test |
| 53 |
fun aFailedDraftStillOpensTheRepositoryAndSaysWhy() { |
| 54 |
api.starterAssistants = { listOf(StarterAssistant("Helper")) } |
| 55 |
api.starterStatuses = mutableListOf(StarterStatus("failed", "Helper", error = "the assistant answered without any files")) |
| 56 |
val vm = NewRepositoryViewModel(api, "andymccall", pollMs = 10) |
| 57 |
vm.create("andymccall", "pong", "", Visibility.Public, ask = "something") |
| 58 |
main.dispatcher.scheduler.advanceUntilIdle() |
| 59 |
val failed = vm.making.value as Making.Failed |
| 60 |
assertTrue(failed.message, failed.message.contains("without any files")) |
| 61 |
assertEquals("pong", failed.repo?.name) |
| 62 |
} |
| 63 |
|
| 64 |
@Test |
| 65 |
fun aPhoneWithoutRepoAdminIsToldHowToAllowIt() { |
| 66 |
api.createRepository = { _, _, _, _ -> throw HubException.Http(403, "this token lacks the repo:admin scope") } |
| 67 |
val vm = NewRepositoryViewModel(api, "andymccall") |
| 68 |
vm.create("andymccall", "pong", "", Visibility.Public, ask = "") |
| 69 |
val failed = vm.making.value as Making.Failed |
| 70 |
assertTrue(failed.message, failed.message.contains("sign out and in again")) |
| 71 |
} |
| 72 |
|
| 73 |
private fun run(repo: String, n: Long, status: String, created: Long, finished: Long? = null, jobs: List<String> = emptyList()) = |
| 74 |
UserFlowRun(repo, FlowRun(number = n, status = status, createdMs = created, finishedMs = finished, jobs = jobs.map { FlowJob(name = it, status = status) })) |
| 75 |
|
| 76 |
@Test |
| 77 |
fun theMonitorFiltersDrawsAndTimesRuns() { |
| 78 |
val runs = listOf( |
| 79 |
run("andy/a", 3, "running", 9_000), |
| 80 |
run("andy/b", 2, "failed", 5_000, 8_000), |
| 81 |
run("andy/a", 1, "passed", 1_000, 200_000, jobs = listOf("build", "test")), |
| 82 |
) |
| 83 |
assertEquals(listOf(3L), filtered(runs, RunFilter.Live).map { it.run.number }) |
| 84 |
assertEquals(listOf(2L), filtered(runs, RunFilter.Failed).map { it.run.number }) |
| 85 |
assertEquals(3, filtered(runs, RunFilter.All).size) |
| 86 |
val sky = runSky(runs, now = 10_000) |
| 87 |
assertEquals(listOf("andy/a", "andy/b"), sky.repos) |
| 88 |
assertEquals(listOf(listOf(0L, 4L, 9_000L, 1L), listOf(1L, 4L, 5_000L, 1L), listOf(0L, 4L, 1_000L, 1L)), sky.events) |
| 89 |
assertEquals("3 s", took(runs[1].run, now = 10_000)) |
| 90 |
assertEquals("3 min 19 s", took(runs[2].run, now = 0)) |
| 91 |
assertEquals("1 s", took(runs[0].run, now = 10_000), ) |
| 92 |
} |
| 93 |
} |