Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
Kotlin
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219package social.grain
import androidx.compose.ui.test.junit4.v2.createComposeRuleimport androidx.compose.ui.test.onNodeWithTextimport androidx.compose.ui.test.performClickimport androidx.test.ext.junit.runners.AndroidJUnit4import org.junit.Afterimport org.junit.Assert.assertEqualsimport org.junit.Beforeimport org.junit.Ruleimport org.junit.Testimport org.junit.runner.RunWithimport social.grain.feature.notifications.NotificationsScreenimport social.grain.feature.notifications.NotificationsViewModelimport social.grain.feature.notifications.UnseenNotificationCountimport social.grain.support.Fixturesimport social.grain.support.Harnessimport social.grain.support.awaitContentDescriptionimport social.grain.support.awaitTextimport social.grain.support.MainDispatcherRuleimport social.grain.support.appContextimport social.grain.support.json
/** * The notifications list as a reader sees it. * * Grouping is the whole point of the screen — "Alice and 2 others favorited * your gallery" is one row — and the sentence it builds is assembled in the * composable, so nothing below it can catch a wrong one. */@RunWith(AndroidJUnit4::class)class NotificationsScreenTest {
@get:Rule val mainDispatcher = MainDispatcherRule()
@get:Rule val composeRule = createComposeRule()
private lateinit var harness: Harness
private val nsid = "social.grain.unspecced.getNotifications"
private fun page(vararg items: String) = """{"notifications":[${items.joinToString(",")}],"unseenCount":1}"""
@Before fun setUp() { harness = Harness() }
@After fun tearDown() = harness.tearDown()
private fun show( onOpenGallery: (String) -> Unit = {}, onOpenProfile: (String) -> Unit = {}, ) { val model = NotificationsViewModel( harness.client, harness.auth, UnseenNotificationCount(appContext, harness.client, harness.auth), ) composeRule.setContent { social.grain.ui.theme.GrainTheme { NotificationsScreen( onOpenGallery = onOpenGallery, onOpenProfile = onOpenProfile, viewModel = model, ) } } composeRule.waitForIdle() }
@Test fun anAccountWithNothingWaitingIsToldSo() { harness.server.on(nsid, page()) show()
composeRule.awaitText("Notifications") composeRule.awaitText("Nothing yet") composeRule.onNodeWithText("Favorites, comments and follows will show up here.") .assertExists() }
@Test fun oneFavoriteReadsAsOnePersonFavoritingOneGallery() { harness.server.on(nsid, page(json(Fixtures.notification()))) show()
composeRule.awaitText("Alice favorited your gallery", substring = true) composeRule.awaitText("A walk in the fog") }
@Test fun severalFavoritesOnOneGalleryCollapseIntoOneSentence() { harness.server.on( nsid, page( json(Fixtures.notification(rkey = "n1")), json( Fixtures.notification( rkey = "n2", author = Fixtures.profile(did = "did:plc:bob", displayName = "Bob"), ), ), json( Fixtures.notification( rkey = "n3", author = Fixtures.profile(did = "did:plc:carol", displayName = "Carol"), ), ), ), ) show()
composeRule.awaitText("Alice and 2 others favorited your gallery", substring = true) }
@Test fun twoPeopleReadAsOneOther() { harness.server.on( nsid, page( json(Fixtures.notification(rkey = "n1")), json( Fixtures.notification( rkey = "n2", author = Fixtures.profile(did = "did:plc:bob", displayName = "Bob"), ), ), ), ) show()
composeRule.awaitText("Alice and 1 other favorited your gallery", substring = true) }
/** Three at a time: a lazy list only composes what fits on screen. */ @Test fun followsCommentsAndRepliesEachReadDifferently() { harness.server.on( nsid, page( json(Fixtures.notification(rkey = "n1", reason = "follow", galleryUri = null)), json( Fixtures.notification( rkey = "n2", reason = "gallery-comment", commentText = "Lovely light", ), ), json(Fixtures.notification(rkey = "n3", reason = "reply")), ), ) show()
composeRule.awaitText("followed you", substring = true) composeRule.awaitText("commented on your gallery", substring = true) composeRule.awaitText("Lovely light") composeRule.awaitText("replied to your comment", substring = true) }
@Test fun mentionsStoriesAndAnUnknownReasonAreAllHandled() { harness.server.on( nsid, page( json(Fixtures.notification(rkey = "n4", reason = "gallery-mention")), json(Fixtures.notification(rkey = "n5", reason = "story-favorite")), json(Fixtures.notification(rkey = "n6", reason = "who-knows")), ), ) show()
composeRule.awaitText("mentioned you in a gallery", substring = true) composeRule.awaitText("favorited your story", substring = true) composeRule.onNodeWithText("A reason this build has never heard of says nothing rather than crashing", substring = true) .assertDoesNotExist() }
@Test fun tappingARowOpensTheGalleryItIsAbout() { harness.server.on(nsid, page(json(Fixtures.notification()))) var opened: String? = null show(onOpenGallery = { opened = it })
composeRule.onNodeWithText("Alice favorited your gallery", substring = true).performClick()
assertEquals("at://did:plc:alice/social.grain.gallery/gallery1", opened) }
@Test fun aFollowHasNoGalleryToOpenSoItOpensTheProfileInstead() { harness.server.on( nsid, page(json(Fixtures.notification(reason = "follow", galleryUri = null))), ) var profile: String? = null show(onOpenProfile = { profile = it })
composeRule.onNodeWithText("Alice followed you", substring = true).performClick()
assertEquals("did:plc:alice", profile) }
/** Arriving clears the badge, without waiting for a scroll to the bottom. */ @Test fun openingTheScreenIsTheReadReceipt() { harness.server.on(nsid, page(json(Fixtures.notification()))) show()
composeRule.waitUntil(10_000) { harness.server.countOf("dev.hatk.putPreference") == 1 } }}