1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package social.grain
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import social.grain.feature.explore.ExploreViewModel
import social.grain.support.Fixtures
import social.grain.support.Harness
import social.grain.support.MainDispatcherRule
import social.grain.support.awaitCall
import social.grain.support.awaitValue
import social.grain.support.json
/**
* Explore: the recent feed paged like any other, plus two chip rows that
* arrive and fail on their own.
*/
@RunWith(AndroidJUnit4::class)
class ExploreViewModelTest {
@get:Rule
val mainDispatcher = MainDispatcherRule()
private lateinit var harness: Harness
@Before
fun setUp() {
harness = Harness()
harness.server
.on("social.grain.feed.getFeed", """{"items":[${json(Fixtures.gallery())}]}""")
.on(
"social.grain.gallery.getCameras",
"""{"cameras":[{"camera":"Leica M6","photoCount":120}]}""",
)
.on(
"social.grain.gallery.getLocations",
"""{"locations":[{"name":"Lisbon, PT","h3Index":"85390cb7fffffff","galleryCount":3}]}""",
)
}
@After
fun tearDown() = harness.tearDown()
private fun model() = ExploreViewModel(
client = harness.client,
auth = harness.auth,
labelDefsCache = harness.labelDefinitions,
)
@Test
fun theGridIsTheRecentFeed() {
val model = model()
val state = model.state.awaitValue("the first page") { it.galleries.isNotEmpty() }
assertEquals("A walk in the fog", state.galleries.single().title)
assertEquals("recent", harness.server.lastCall("social.grain.feed.getFeed").params["feed"]?.substringAfterLast('/'))
}
@Test
fun theChipsComeFromBothIndexes() {
val model = model()
val discovery = model.discovery.awaitValue("both indexes") {
it.cameras.isNotEmpty() && it.locations.isNotEmpty()
}
assertEquals("Leica M6", discovery.cameras.single().camera)
assertEquals("Lisbon, PT", discovery.locations.single().name)
assertEquals("85390cb7fffffff", discovery.locations.single().h3Index)
}
@Test
fun oneIndexFailingLeavesTheOther() {
harness.server.on("social.grain.gallery.getCameras", """{"error":"no"}""", code = 500)
val model = model()
val discovery = model.discovery.awaitValue("the locations") { it.locations.isNotEmpty() }
harness.server.awaitCall("social.grain.gallery.getCameras")
assertTrue(discovery.cameras.isEmpty())
assertEquals("Lisbon, PT", discovery.locations.single().name)
}
@Test
fun pullingToRefreshReReadsTheChipsAsWellAsTheGalleries() {
val model = model()
model.state.awaitValue("the first page") { it.galleries.isNotEmpty() }
harness.server.awaitCall("social.grain.gallery.getCameras")
harness.server.awaitCall("social.grain.gallery.getLocations")
val feeds = harness.server.countOf("social.grain.feed.getFeed")
val cameras = harness.server.countOf("social.grain.gallery.getCameras")
val locations = harness.server.countOf("social.grain.gallery.getLocations")
model.refreshAll()
harness.server.awaitCall("social.grain.feed.getFeed", feeds + 1)
harness.server.awaitCall("social.grain.gallery.getCameras", cameras + 1)
harness.server.awaitCall("social.grain.gallery.getLocations", locations + 1)
model.state.awaitValue("the refresh to finish") { !it.isRefreshing }
}
}