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("dev.hatk.describeLabels", """{"definitions":[]}""") .on("dev.hatk.getFeed", """{"items":[${json(Fixtures.gallery())}]}""") .on( "social.grain.unspecced.getCameras", """{"cameras":[{"camera":"Leica M6","photoCount":120}]}""", ) .on( "social.grain.unspecced.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("dev.hatk.getFeed").params["feed"]) } @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.unspecced.getCameras", """{"error":"no"}""", code = 500) val model = model() val discovery = model.discovery.awaitValue("the locations") { it.locations.isNotEmpty() } harness.server.awaitCall("social.grain.unspecced.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.unspecced.getCameras") harness.server.awaitCall("social.grain.unspecced.getLocations") val feeds = harness.server.countOf("dev.hatk.getFeed") val cameras = harness.server.countOf("social.grain.unspecced.getCameras") val locations = harness.server.countOf("social.grain.unspecced.getLocations") model.refreshAll() harness.server.awaitCall("dev.hatk.getFeed", feeds + 1) harness.server.awaitCall("social.grain.unspecced.getCameras", cameras + 1) harness.server.awaitCall("social.grain.unspecced.getLocations", locations + 1) model.state.awaitValue("the refresh to finish") { !it.isRefreshing } } }