Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
Kotlin
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174package social.grain
import androidx.compose.foundation.text.input.setTextAndPlaceCursorAtEndimport 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.data.api.ReportSubjectimport social.grain.feature.moderation.ReportViewModelimport social.grain.support.Harnessimport social.grain.support.MainDispatcherRuleimport social.grain.support.awaitCallimport social.grain.support.awaitValueimport social.grain.support.settle
/** * The report sheet. * * The category list comes from the server because the server rejects anything * it doesn't publish — a stale local list would fail the submit with nothing * the reporter could do about it. Reopening the sheet has to start blank, or * the second report on the same gallery opens onto the first one's receipt. */@RunWith(AndroidJUnit4::class)class ReportViewModelTest {
@get:Rule val mainDispatcher = MainDispatcherRule()
private lateinit var harness: Harness
private val subject = ReportSubject.Record("at://did:plc:alice/social.grain.gallery/g1", "cid1")
private val categories = """{"definitions":[{"identifier":"spam","locales":[{"name":"Spam"}]},""" + """{"identifier":"porn","locales":[{"name":"Adult Content"}]}]}"""
@Before fun setUp() { harness = Harness() harness.server.on("dev.hatk.describeLabels", categories) }
@After fun tearDown() = harness.tearDown()
private fun viewModel() = ReportViewModel(harness.client, harness.auth)
@Test fun openingTheSheetFetchesTheCategoriesAndPreSelectsTheFirst() { val model = viewModel() model.start(subject)
val state = model.state.awaitValue("the categories") { !it.isLoadingCategories } assertEquals(2, state.categories.size) assertEquals("spam", state.selected) assertTrue(state.canSubmit) }
@Test fun categoriesAreFetchedOnceAndKeptAcrossOpenings() { val model = viewModel() model.start(subject) model.state.awaitValue("the categories") { !it.isLoadingCategories }
model.start(ReportSubject.Account("did:plc:bob")) settle()
assertEquals(1, harness.server.countOf("dev.hatk.describeLabels")) assertFalse(model.state.value.isLoadingCategories) }
@Test fun reopeningTheSheetClearsTheReceiptFromLastTime() { val model = viewModel() model.start(subject) model.state.awaitValue("the categories") { !it.isLoadingCategories } model.submit() model.state.awaitValue("the receipt") { it.isSubmitted }
model.start(subject)
assertFalse("A fresh report doesn't open onto the last one", model.state.value.isSubmitted) }
@Test fun categoriesThatFailToLoadSayeSo() { harness.server.on("dev.hatk.describeLabels", """{"error":"no"}""", code = 500) val model = viewModel() model.start(subject)
val state = model.state.awaitValue("the error") { it.errorMessage != null } assertEquals("Couldn't load report categories.", state.errorMessage) assertFalse(state.isLoadingCategories) assertFalse("Nothing selected means nothing to submit", state.canSubmit)
model.dismissError() assertNull(model.state.value.errorMessage) }
@Test fun submittingSendsTheChosenLabelAndTheTypedReason() { harness.server.on("dev.hatk.createReport", """{"id":1}""") val model = viewModel() model.start(subject) model.state.awaitValue("the categories") { !it.isLoadingCategories }
model.select("porn") model.reasonState.setTextAndPlaceCursorAtEnd(" Not okay ") model.submit()
model.state.awaitValue("the receipt") { it.isSubmitted } val body = harness.server.awaitCall("dev.hatk.createReport").body assertTrue(body.contains("\"label\":\"porn\"")) assertTrue("Whitespace is trimmed off the reason", body.contains("\"reason\":\"Not okay\"")) assertTrue(body.contains("com.atproto.repo.strongRef")) }
@Test fun anEmptyReasonIsLeftOutEntirely() { harness.server.on("dev.hatk.createReport", """{"id":1}""") val model = viewModel() model.start(subject) model.state.awaitValue("the categories") { !it.isLoadingCategories }
model.submit()
model.state.awaitValue("the receipt") { it.isSubmitted } assertFalse(harness.server.awaitCall("dev.hatk.createReport").body.contains("reason")) }
@Test fun reportingAnAccountSendsABareDid() { harness.server.on("dev.hatk.createReport", """{"id":1}""") val model = viewModel() model.start(ReportSubject.Account("did:plc:bob")) model.state.awaitValue("the categories") { !it.isLoadingCategories }
model.submit()
model.state.awaitValue("the receipt") { it.isSubmitted } assertTrue(harness.server.awaitCall("dev.hatk.createReport").body.contains("\"did\":\"did:plc:bob\"")) }
@Test fun aSubmitThatFailsSaysSoAndLeavesTheFormUsable() { harness.server.on("dev.hatk.createReport", """{"error":"no"}""", code = 500) val model = viewModel() model.start(subject) model.state.awaitValue("the categories") { !it.isLoadingCategories }
model.submit()
val state = model.state.awaitValue("the error") { it.errorMessage != null } assertEquals("Couldn't submit that report. Try again.", state.errorMessage) assertFalse(state.isSubmitted) assertTrue(state.canSubmit) }
@Test fun submittingBeforeTheSheetHasASubjectDoesNothing() { val model = viewModel() model.submit() settle() assertEquals(0, harness.server.countOf("dev.hatk.createReport")) }}