Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
Kotlin
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190package social.grain
import androidx.compose.ui.test.junit4.v2.createComposeRuleimport androidx.compose.ui.test.onNodeWithTextimport androidx.compose.ui.test.performClickimport androidx.compose.ui.test.performScrollToimport androidx.test.ext.junit.runners.AndroidJUnit4import org.junit.Afterimport org.junit.Assert.assertEqualsimport org.junit.Assert.assertFalseimport org.junit.Assert.assertTrueimport org.junit.Beforeimport org.junit.Ruleimport org.junit.Testimport org.junit.runner.RunWithimport social.grain.data.auth.SecureStoreimport social.grain.data.local.Appearanceimport social.grain.data.local.AppearanceStoreimport social.grain.data.push.PushManagerimport social.grain.feature.settings.SettingsScreenimport social.grain.feature.settings.SettingsViewModelimport social.grain.support.Harnessimport social.grain.support.awaitContentDescriptionimport social.grain.support.awaitTextimport social.grain.support.MainDispatcherRuleimport social.grain.support.appContextimport social.grain.ui.theme.GrainTheme
/** * Settings, including the two dialogs that guard the irreversible rows. * * Sign-out and account deletion both go through a confirmation, and both of * those are pure composable state — nothing below this can tell whether the * dialog appeared, or whether cancelling it left the account alone. */@RunWith(AndroidJUnit4::class)class SettingsScreenTest {
@get:Rule val mainDispatcher = MainDispatcherRule()
@get:Rule val composeRule = createComposeRule()
private lateinit var harness: Harness private lateinit var appearance: AppearanceStore
@Before fun setUp() { harness = Harness() appearance = AppearanceStore(appContext) appearance.set(Appearance.AUTOMATIC) harness.server.on( "dev.hatk.getPreferences", """{"preferences":{"includeExif":true,"includeLocation":false}}""", ) }
@After fun tearDown() { appearance.set(Appearance.AUTOMATIC) harness.tearDown() }
private fun show( onBack: () -> Unit = {}, onEditProfile: () -> Unit = {}, onOpenBlocked: () -> Unit = {}, onOpenMuted: () -> Unit = {}, ) { val model = SettingsViewModel( harness.client, harness.auth, PushManager(appContext, harness.client, harness.auth, SecureStore(appContext), harness.scope), appearance, ) composeRule.setContent { GrainTheme { SettingsScreen( onBack = onBack, onEditProfile = onEditProfile, onOpenBlocked = onOpenBlocked, onOpenMuted = onOpenMuted, viewModel = model, ) } } composeRule.waitForIdle() }
@Test fun theScreenNamesTheSignedInAccountAndItsSections() { show()
composeRule.awaitText("Settings") composeRule.onNodeWithText(harness.handle).assertExists() composeRule.awaitText("Edit profile") composeRule.awaitText("Appearance") composeRule.awaitText("Defaults for new uploads") }
@Test fun theUploadSwitchesShowWhatTheServerHolds() { show()
composeRule.awaitText("Include camera data") composeRule.awaitText("Publish EXIF alongside each photo.") composeRule.awaitText("Include location") }
@Test fun theBackButtonAndTheProfileRowReportTheirTaps() { var back = 0 var edit = 0 show(onBack = { back += 1 }, onEditProfile = { edit += 1 })
composeRule.onNodeWithText("Edit profile").performClick() composeRule.onNodeWithContentDescriptionCompat("Back").performClick()
assertEquals(1, edit) assertEquals(1, back) }
@Test fun choosingAnAppearanceStoresIt() { show()
composeRule.onNodeWithText("Dark").performScrollTo().performClick()
assertEquals(Appearance.DARK, appearance.appearance.value) }
@Test fun signingOutGoesThroughAConfirmationThatCanBeCancelled() { show()
composeRule.onNodeWithText("Sign out").performScrollTo().performClick() composeRule.awaitText("Sign out?") composeRule.awaitText("You'll need to sign in again to use Grain.")
composeRule.onNodeWithText("Cancel").performClick()
assertTrue("Cancelling leaves the session alone", harness.auth.state.value.isAuthenticated) }
@Test fun confirmingTheSignOutEndsTheSession() { show()
composeRule.onNodeWithText("Sign out").performScrollTo().performClick() composeRule.onAllNodesWithTextCompat("Sign out")[1].performClick() composeRule.waitForIdle()
assertFalse(harness.auth.state.value.isAuthenticated) }
@Test fun deletingTheAccountGoesThroughItsOwnConfirmation() { show()
composeRule.onNodeWithText("Delete account").performScrollTo().performClick() composeRule.awaitText("Delete account?")
composeRule.onNodeWithText("Cancel").performClick() composeRule.waitForIdle()
assertEquals(0, harness.server.countOf("social.grain.unspecced.deleteAccount")) }
@Test fun theModerationRowsLeadToTheirLists() { var blocked = 0 var muted = 0 show(onOpenBlocked = { blocked += 1 }, onOpenMuted = { muted += 1 })
composeRule.onNodeWithText("Blocked users").performScrollTo().performClick() composeRule.onNodeWithText("Muted users").performScrollTo().performClick()
assertEquals(1, blocked) assertEquals(1, muted) }}
private fun androidx.compose.ui.test.junit4.ComposeTestRule.onNodeWithContentDescriptionCompat( value: String,) = onNode(androidx.compose.ui.test.hasContentDescription(value))
private fun androidx.compose.ui.test.junit4.ComposeTestRule.onAllNodesWithTextCompat(value: String) = onAllNodes(androidx.compose.ui.test.hasText(value))