~ knotless Search/
↑↓ move↵ open⇧↵ all results

grain.social/grain-android

1 collaborator
0
1
main
105 lines · 3.7 KB Raw History
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 }
    }
}