Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
Kotlin
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174package social.grain
import androidx.lifecycle.SavedStateHandleimport androidx.test.ext.junit.runners.AndroidJUnit4import org.junit.Afterimport org.junit.Assert.assertEqualsimport org.junit.Assert.assertFalseimport org.junit.Assert.assertNullimport org.junit.Assert.assertTrueimport org.junit.Beforeimport org.junit.Ruleimport org.junit.Testimport org.junit.runner.RunWithimport social.grain.feature.actors.ActorListModeimport social.grain.feature.actors.ActorListViewModelimport social.grain.support.Harnessimport social.grain.support.MainDispatcherRuleimport social.grain.support.awaitValueimport social.grain.support.settle
/** * The one screen behind four lists. * * Each mode has its own endpoint and its own empty-state wording, and only * three of the four paginate — known-followers is a single capped response, so * asking it for more is a request that can never be satisfied. */@RunWith(AndroidJUnit4::class)class ActorListViewModelTest {
@get:Rule val mainDispatcher = MainDispatcherRule()
private lateinit var harness: Harness
private val alice = "did:plc:alice"
private fun actors(vararg dids: String) = dids.joinToString(",") { """{"did":"$it","handle":"${it.substringAfterLast(':')}.test"}""" }
@Before fun setUp() { harness = Harness() }
@After fun tearDown() = harness.tearDown()
private fun viewModel(mode: ActorListMode, subject: String = alice) = ActorListViewModel( client = harness.client, auth = harness.auth, savedStateHandle = SavedStateHandle(mapOf("mode" to mode, "subject" to subject)), )
@Test fun followersLoadFromTheirOwnEndpointWithTheViewerAttached() { harness.server.on( "social.grain.unspecced.getFollowers", """{"totalCount":2,"items":[${actors("did:plc:bob", "did:plc:carol")}]}""", ) val model = viewModel(ActorListMode.FOLLOWERS) val state = model.state.awaitValue("the list") { it.hasLoaded }
assertEquals(2, state.items.size) assertEquals(2, state.totalCount) assertFalse(state.isLoading) assertEquals("Followers", state.title) assertEquals("No followers", state.emptyTitle)
val call = harness.server.lastCall("social.grain.unspecced.getFollowers") assertEquals(alice, call.params["actor"]) assertEquals(harness.did, call.params["viewer"]) }
@Test fun followingHasItsOwnEndpointAndWording() { harness.server.on( "social.grain.unspecced.getFollowing", """{"items":[${actors("did:plc:bob")}]}""", ) val state = viewModel(ActorListMode.FOLLOWING).state.awaitValue("the list") { it.hasLoaded }
assertEquals("Following", state.title) assertEquals("No following", state.emptyTitle) assertEquals("This account isn't following anyone yet.", state.emptyDescription) }
@Test fun knownFollowersIsOneCappedResponseWithNothingMoreToAskFor() { harness.server.on( "social.grain.unspecced.getKnownFollowers", """{"items":[${actors("did:plc:bob")}]}""", ) val model = viewModel(ActorListMode.KNOWN_FOLLOWERS) val state = model.state.awaitValue("the list") { it.hasLoaded }
assertEquals("Followers you know", state.title) assertNull(state.totalCount)
model.loadMore() settle() assertEquals(1, harness.server.countOf("social.grain.unspecced.getKnownFollowers")) }
@Test fun galleryFavoritesTakeAGalleryUriAsTheirSubject() { val gallery = "at://did:plc:alice/social.grain.gallery/g1" harness.server.on( "social.grain.unspecced.getGalleryFavorites", """{"totalCount":1,"items":[${actors("did:plc:bob")}]}""", ) val state = viewModel(ActorListMode.GALLERY_FAVORITES, subject = gallery) .state.awaitValue("the list") { it.hasLoaded }
assertEquals("Favorited by", state.title) assertEquals("No one has favorited this gallery yet.", state.emptyDescription) assertEquals( gallery, harness.server.lastCall("social.grain.unspecced.getGalleryFavorites").params["gallery"], ) }
@Test fun asecondPageIsAppendedRatherThanReplacing() { harness.server.on( "social.grain.unspecced.getFollowers", """{"totalCount":2,"items":[${actors("did:plc:bob")}],"cursor":"c1"}""", ) val model = viewModel(ActorListMode.FOLLOWERS) model.state.awaitValue("the first page") { it.hasLoaded }
harness.server.on( "social.grain.unspecced.getFollowers", """{"items":[${actors("did:plc:carol")}]}""", ) model.loadMore()
val state = model.state.awaitValue("the second page") { it.items.size == 2 } assertEquals("The count from the first page is kept", 2, state.totalCount) }
@Test fun aListWithNoCursorHasNothingMoreToLoad() { harness.server.on( "social.grain.unspecced.getFollowers", """{"items":[${actors("did:plc:bob")}]}""", ) val model = viewModel(ActorListMode.FOLLOWERS) model.state.awaitValue("the list") { it.hasLoaded }
model.loadMore() settle()
assertEquals(1, harness.server.countOf("social.grain.unspecced.getFollowers")) }
@Test fun aFailedLoadReportsItsMessageAndCanBeRetried() { harness.server.on("social.grain.unspecced.getFollowers", """{"error":"no"}""", code = 500) val model = viewModel(ActorListMode.FOLLOWERS)
val state = model.state.awaitValue("the error") { it.errorMessage != null } assertEquals("HTTP error 500", state.errorMessage) assertTrue(state.hasLoaded)
model.dismissError() assertNull(model.state.value.errorMessage)
harness.server.on("social.grain.unspecced.getFollowers", """{"items":[${actors("did:plc:bob")}]}""") model.reload() model.state.awaitValue("the retry") { it.items.isNotEmpty() } }}