Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
Kotlin
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173package 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.settings.ModerationModeimport social.grain.feature.settings.ModerationViewModelimport social.grain.support.Harnessimport social.grain.support.MainDispatcherRuleimport social.grain.support.awaitCallimport social.grain.support.awaitValueimport social.grain.support.settle
/** * The blocked and muted lists in Settings. * * A row here leaves only once the write lands — unlike a favourite, this is a * list of deliberate decisions, and a row that vanishes and then comes back * reads as the app undoing something the reader chose. */@RunWith(AndroidJUnit4::class)class ModerationViewModelTest {
@get:Rule val mainDispatcher = MainDispatcherRule()
private lateinit var harness: Harness
@Before fun setUp() { harness = Harness() }
@After fun tearDown() = harness.tearDown()
private fun viewModel(mode: ModerationMode) = ModerationViewModel( client = harness.client, auth = harness.auth, savedStateHandle = SavedStateHandle(mapOf("mode" to mode)), )
@Test fun theBlockedListCarriesTheRecordUriThatUndoesEachBlock() { harness.server.on( "social.grain.unspecced.getBlocks", """{"items":[{"did":"did:plc:bob","handle":"bob.test","blockUri":"at://did:plc:me/social.grain.graph.block/b1"}]}""", ) val model = viewModel(ModerationMode.BLOCKED) val state = model.state.awaitValue("the list") { !it.isLoading }
assertEquals("Blocked users", state.title) assertEquals("Unblock", state.actionLabel) assertEquals("You haven't blocked anyone.", state.emptyText) assertEquals("at://did:plc:me/social.grain.graph.block/b1", state.actors.single().blockUri) }
@Test fun theMutedListHasNoRecordToDeleteAndItsOwnWording() { harness.server.on( "social.grain.unspecced.getMutes", """{"items":[{"did":"did:plc:carol","handle":"carol.test"}]}""", ) val state = viewModel(ModerationMode.MUTED).state.awaitValue("the list") { !it.isLoading }
assertEquals("Muted users", state.title) assertEquals("Unmute", state.actionLabel) assertEquals("You haven't muted anyone.", state.emptyText) assertNull(state.actors.single().blockUri) }
@Test fun unblockingDeletesTheRecordAndThenRemovesTheRow() { harness.server.on( "social.grain.unspecced.getBlocks", """{"items":[{"did":"did:plc:bob","blockUri":"at://did:plc:me/social.grain.graph.block/b1"}]}""", ) val model = viewModel(ModerationMode.BLOCKED) val actor = model.state.awaitValue("the list") { it.actors.isNotEmpty() }.actors.single()
model.remove(actor)
assertTrue(harness.server.awaitCall("dev.hatk.deleteRecord").body.contains("\"rkey\":\"b1\"")) val state = model.state.awaitValue("the row to go") { it.actors.isEmpty() } assertTrue(state.pending.isEmpty()) }
@Test fun unmutingCallsTheGraphEndpoint() { harness.server.on( "social.grain.unspecced.getMutes", """{"items":[{"did":"did:plc:carol"}]}""", ) val model = viewModel(ModerationMode.MUTED) val actor = model.state.awaitValue("the list") { it.actors.isNotEmpty() }.actors.single()
model.remove(actor)
assertTrue( harness.server.awaitCall("social.grain.graph.unmuteActor").body.contains("did:plc:carol"), ) model.state.awaitValue("the row to go") { it.actors.isEmpty() } }
@Test fun aRemovalThatFailsKeepsTheRowAndSaysSo() { harness.server .on( "social.grain.unspecced.getBlocks", """{"items":[{"did":"did:plc:bob","blockUri":"at://x/social.grain.graph.block/b1"}]}""", ) .on("dev.hatk.deleteRecord", """{"error":"no"}""", code = 500) val model = viewModel(ModerationMode.BLOCKED) val actor = model.state.awaitValue("the list") { it.actors.isNotEmpty() }.actors.single()
model.remove(actor)
val state = model.state.awaitValue("the error") { it.errorMessage != null } assertEquals(1, state.actors.size) assertEquals("Couldn't do that. Try again.", state.errorMessage) assertTrue(state.pending.isEmpty())
model.dismissError() assertNull(model.state.value.errorMessage) }
@Test fun signedOutThereIsNothingToListAndNothingToUndo() { harness.tearDown() harness = Harness(signedIn = false) val model = viewModel(ModerationMode.BLOCKED)
val state = model.state.awaitValue("the load to finish") { !it.isLoading } assertTrue(state.actors.isEmpty()) assertEquals( "A signed-out viewer has no lists to read", 0, harness.server.countOf("social.grain.unspecced.getBlocks"), )
model.remove( social.grain.feature.settings.ModeratedActor( did = "did:plc:bob", handle = null, displayName = null, avatar = null, blockUri = "at://x/social.grain.graph.block/b1", ), ) settle() assertEquals(0, harness.server.countOf("dev.hatk.deleteRecord")) assertTrue(model.state.value.pending.isEmpty()) }
@Test fun aFailedListLoadSaysSo() { harness.server.on("social.grain.unspecced.getBlocks", """{"error":"no"}""", code = 500) val state = viewModel(ModerationMode.BLOCKED) .state.awaitValue("the error") { it.errorMessage != null }
assertEquals("Couldn't load that list.", state.errorMessage) assertFalse(state.isLoading) }}