OXYGENHUB
◆ v0.1.4 oxygenhub-android / app / src / test / java / io / oxygenhub / android / ui / WidgetDataTest.kt
5.1 KiB · last changed The widget's foot: a white mark and title, counts of unread, reviews and assigned issues that open their screens, and the phone's runner job; Assigned to you on the dashboard (closes #31) 3 days ago source blame history raw
1
package io.oxygenhub.android.ui
2
3
import io.oxygenhub.android.FakeHubApi
4
import io.oxygenhub.android.api.FlowRun
5
import io.oxygenhub.android.api.HubException
6
import io.oxygenhub.android.api.UserFlowRun
7
import io.oxygenhub.android.api.UserSky
8
import io.oxygenhub.android.api.IssueBrief
9
import io.oxygenhub.android.ui.nav.AccountRoute
10
import io.oxygenhub.android.ui.nav.DashboardRoute
11
import io.oxygenhub.android.ui.nav.InboxRoute
12
import io.oxygenhub.android.ui.nav.IssueRoute
13
import io.oxygenhub.android.ui.nav.ProposalRoute
14
import io.oxygenhub.android.widget.SkyBitmap
15
import io.oxygenhub.android.widget.WidgetData
16
import io.oxygenhub.android.widget.WidgetTaps
17
import io.oxygenhub.android.widget.runnerLine
18
import kotlinx.coroutines.test.runTest
19
import org.junit.Assert.assertEquals
20
import org.junit.Assert.assertFalse
21
import org.junit.Assert.assertNotEquals
22
import org.junit.Assert.assertNull
23
import org.junit.Assert.assertTrue
24
import org.junit.Test
25
26
class WidgetDataTest {
27
    @Test
28
    fun theWidgetShowsTheLatestRunsAndCountsAndAsksForASignInWithoutOne() = runTest {
29
        val api = FakeHubApi()
30
        api.userFlowRuns = { (1L..5L).map { UserFlowRun("andy/a", FlowRun(number = it, status = "passed")) } }
31
        val d = WidgetData.load(api)
32
        assertEquals(listOf(1L, 2L, 3L), d.runs.map { it.run.number })
33
        assertEquals(1, d.reviews)
34
        assertFalse(WidgetData.load(null).signedIn)
35
    }
36
37
    @Test
38
    fun aPartTheHubCannotGiveIsLeftOutNotTheWholeWidget() = runTest {
39
        val api = FakeHubApi()
40
        api.userFlowRuns = { throw HubException.Http(404, "no such API route") }
41
        val d = WidgetData.load(api)
42
        assertEquals(emptyList<UserFlowRun>(), d.runs)
43
        assertEquals(1, d.reviews)
44
        api.userProposals = { throw HubException.Http(500, "down") }
45
        assertNull(WidgetData.load(api).reviews)
46
    }
47
48
    @Test
49
    fun theWidgetFetchesYourSkyAndALostSkyLeavesThePlainSurface() = runTest {
50
        val api = FakeHubApi()
51
        val sky = UserSky(now = 10 * 86_400_000L, repos = listOf("andy/a"), events = listOf(listOf(0L, 0L, 9 * 86_400_000L, 3L)))
52
        api.userSky = { sky }
53
        assertEquals(sky, WidgetData.load(api).sky)
54
        api.userSky = { throw HubException.Http(404, "no such API route") }
55
        val d = WidgetData.load(api)
56
        assertNull(d.sky)
57
        assertEquals(1, d.reviews)
58
    }
59
60
    @Test
61
    fun onlyRealActivityIsDrawn() {
62
        assertFalse("nothing fetched", SkyBitmap.drawable(null))
63
        assertFalse("no repositories", SkyBitmap.drawable(UserSky()))
64
        assertFalse("repositories but no events", SkyBitmap.drawable(UserSky(repos = listOf("andy/a"))))
65
        assertFalse("only malformed events", SkyBitmap.drawable(UserSky(repos = listOf("andy/a"), events = listOf(listOf(7L, 0L, 0L, 1L)))))
66
        assertTrue(SkyBitmap.drawable(UserSky(now = 1, repos = listOf("andy/a"), events = listOf(listOf(0L, 4L, 0L, 1L)))))
67
    }
68
69
    @Test
70
    fun theSkysColoursFollowTheTheme() {
71
        val (light, dark) = SkyBitmap.colours(false) to SkyBitmap.colours(true)
72
        assertEquals(24, light.size)
73
        assertEquals(24, dark.size)
74
        assertNotEquals(light, dark)
75
        assertTrue("every channel is a fraction", (light + dark).all { it in 0f..1f })
76
    }
77
78
    @Test
79
    fun theCountsRowSaysWhatIsAssignedAndOneOfAKindOpensItself() = runTest {
80
        val api = FakeHubApi()
81
        val d = WidgetData.load(api)
82
        assertEquals(1, d.assigned)
83
        assertEquals(359L, d.onlyAssigned?.number)
84
        assertEquals(300L, d.onlyReview?.number)
85
        api.userIssues = { listOf(IssueBrief("andy/a", 1), IssueBrief("andy/a", 2)) }
86
        val two = WidgetData.load(api)
87
        assertEquals(2, two.assigned)
88
        assertNull("two open the dashboard, not one of them", two.onlyAssigned)
89
        api.userIssues = { throw HubException.Http(404, "no such API route") }
90
        val old = WidgetData.load(api)
91
        assertNull("a hub before /user/issues: the count is left out", old.assigned)
92
        assertEquals(1, old.reviews)
93
    }
94
95
    @Test
96
    fun theRunnerShowsOnlyWhileThePhoneServes() = runTest {
97
        val api = FakeHubApi()
98
        assertNull(WidgetData.load(api).runnerJobs)
99
        assertEquals(listOf("andy/a #7 test"), WidgetData.load(api, listOf("andy/a #7 test")).runnerJobs)
100
        assertEquals("Waiting for jobs", runnerLine(emptyList()))
101
        assertEquals("andy/a #7 test", runnerLine(listOf("andy/a #7 test")))
102
        assertEquals("2 jobs", runnerLine(listOf("andy/a #7 test", "andy/b #2 build")))
103
    }
104
105
    @Test
106
    fun aTapOnACountOpensItsScreen() {
107
        assertEquals(InboxRoute, WidgetTaps.route("inbox", "", 0))
108
        assertEquals(DashboardRoute, WidgetTaps.route("dashboard", "", 0))
109
        assertEquals(AccountRoute, WidgetTaps.route("account", "", 0))
110
        assertEquals(ProposalRoute("andy", "a", 3), WidgetTaps.route("proposal", "andy/a", 3))
111
        assertEquals(IssueRoute("andy", "a", 4), WidgetTaps.route("issue", "andy/a", 4))
112
        assertEquals("a broken reference falls back to the dashboard", DashboardRoute, WidgetTaps.route("issue", "nonsense", 4))
113
        assertNull("not from the widget", WidgetTaps.route(null, null, 0))
114
    }
115
}