Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243package social.grain
import androidx.compose.ui.test.junit4.v2.createComposeRuleimport androidx.compose.ui.test.onNodeWithContentDescriptionimport androidx.compose.ui.test.onNodeWithTextimport androidx.compose.ui.test.performClickimport androidx.compose.ui.test.performTextInputimport androidx.test.ext.junit.runners.AndroidJUnit4import org.junit.Assert.assertEqualsimport org.junit.Assert.assertNullimport org.junit.Ruleimport org.junit.Testimport org.junit.runner.RunWithimport social.grain.data.model.CommentThreadimport social.grain.data.model.GrainCommentimport social.grain.support.Fixturesimport social.grain.support.awaitContentDescriptionimport social.grain.support.awaitTextimport social.grain.ui.components.CommentSheetimport social.grain.ui.theme.GrainTheme
/** * The comment sheet, which is the same component over a gallery and a story. * * Everything interesting about it is composable state rather than view model * state: who the composer is replying to, whether a muted comment stays folded, * and which row actions a reader is offered on their own comment versus someone * else's. */@RunWith(AndroidJUnit4::class)class CommentSheetTest {
@get:Rule val composeRule = createComposeRule()
private val me = Fixtures.profile(did = "did:plc:me", handle = "me.test", displayName = "Me")
private fun show( threads: List<CommentThread> = listOf( CommentThread(Fixtures.comment(text = "Lovely light"), emptyList()), ), viewerDid: String? = "did:plc:me", isPosting: Boolean = false, hasLoaded: Boolean = true, onDismiss: () -> Unit = {}, onPost: (String, GrainComment?) -> Unit = { _, _ -> }, onDelete: (GrainComment) -> Unit = {}, onToggleFavorite: (GrainComment) -> Unit = {}, onProfileTap: (String) -> Unit = {}, onReport: ((GrainComment) -> Unit)? = null, errorMessage: String? = null, onErrorDismissed: () -> Unit = {}, ) { composeRule.setContent { GrainTheme { CommentSheet( threads = threads, viewerDid = viewerDid, isPosting = isPosting, hasLoaded = hasLoaded, onDismiss = onDismiss, onPost = onPost, onDelete = onDelete, onToggleFavorite = onToggleFavorite, onProfileTap = onProfileTap, onLoadMore = {}, onReport = onReport, errorMessage = errorMessage, onErrorDismissed = onErrorDismissed, ) } } composeRule.waitForIdle() }
@Test fun theSheetIsTitledAndShowsTheCommentsItWasGiven() { show()
composeRule.awaitText("Comments") composeRule.awaitText("Lovely light") composeRule.awaitText("Alice") }
@Test fun aThreadWithNothingInItSaysSoOnceItHasLoaded() { show(threads = emptyList())
composeRule.awaitText("No comments yet") }
@Test fun aThreadStillLoadingSaysNothingRatherThanNoCommentsYet() { show(threads = emptyList(), hasLoaded = false)
composeRule.onNodeWithText("No comments yet").assertDoesNotExist() }
@Test fun repliesAreDrawnUnderTheirRoot() { val root = Fixtures.comment(rkey = "root", text = "Root") show( threads = listOf( CommentThread( root, listOf(Fixtures.comment(rkey = "r", text = "A reply", replyTo = root.uri)), ), ), )
composeRule.awaitText("Root") composeRule.awaitText("A reply") }
@Test fun typingAndSendingHandsTheTextUp() { var posted: Pair<String, GrainComment?>? = null show(onPost = { text, replyTo -> posted = text to replyTo })
composeRule.onNodeWithText("Add a comment…").performTextInput("Nice one") composeRule.onNodeWithContentDescription("Send comment").performClick()
assertEquals("Nice one", posted?.first) assertNull("A top-level comment replies to nothing", posted?.second) }
@Test fun replyingNamesWhoIsBeingRepliedToAndCanBeCancelled() { show()
composeRule.onNodeWithText("Reply").performClick() composeRule.awaitText("Replying to @alice.grain.social") composeRule.awaitText("Reply…")
composeRule.onNodeWithText("Cancel").performClick()
composeRule.onNodeWithText("Replying to @alice.grain.social").assertDoesNotExist() composeRule.awaitText("Add a comment…") }
@Test fun sendingAReplyCarriesTheCommentItAnswers() { var posted: Pair<String, GrainComment?>? = null show(onPost = { text, replyTo -> posted = text to replyTo })
composeRule.onNodeWithText("Reply").performClick() composeRule.onNodeWithText("Reply…").performTextInput("Agreed") composeRule.onNodeWithContentDescription("Send comment").performClick()
assertEquals("Agreed", posted?.first) assertEquals("comment1", posted?.second?.rkey) }
@Test fun theViewersOwnCommentOffersDeleteAndNotReport() { var deleted: GrainComment? = null show( threads = listOf(CommentThread(Fixtures.comment(author = me), emptyList())), onDelete = { deleted = it }, onReport = {}, )
composeRule.onNodeWithText("Report").assertDoesNotExist() composeRule.onNodeWithText("Delete").performClick()
assertEquals("comment1", deleted?.rkey) }
@Test fun somebodyElsesCommentOffersReportAndNotDelete() { var reported: GrainComment? = null show(onReport = { reported = it })
composeRule.onNodeWithText("Delete").assertDoesNotExist() composeRule.onNodeWithText("Report").performClick()
assertEquals("comment1", reported?.rkey) }
@Test fun aSignedOutReaderIsOfferedNothingToReportWith() { show(viewerDid = null, onReport = null)
composeRule.onNodeWithText("Report").assertDoesNotExist() composeRule.onNodeWithText("Delete").assertDoesNotExist() }
@Test fun theHeartOnACommentSaysWhichWayItWouldGo() { var toggled: GrainComment? = null show(onToggleFavorite = { toggled = it })
composeRule.onNodeWithContentDescription("Favorite comment").performClick()
assertEquals("comment1", toggled?.rkey) }
@Test fun anAlreadyFavoritedCommentOffersToUndoIt() { show( threads = listOf( CommentThread(Fixtures.comment(favUri = "at://fav/1"), emptyList()), ), )
composeRule.awaitContentDescription("Unfavorite comment") }
@Test fun aMutedCommentIsFoldedAwayUntilTheReaderAsksForIt() { show( threads = listOf( CommentThread( Fixtures.comment(text = "Something unpleasant").copy(muted = true), emptyList(), ), ), )
composeRule.onNodeWithText("Something unpleasant").assertDoesNotExist() composeRule.onNodeWithText("Muted comment").performClick() composeRule.awaitText("Something unpleasant") }
@Test fun anErrorIsShownInsideTheSheetWhereTheReaderCanSeeIt() { var dismissed = 0 show(errorMessage = "Couldn't post that comment.", onErrorDismissed = { dismissed += 1 })
composeRule.awaitText("Couldn't post that comment.") }
@Test fun tappingAnAuthorOpensTheirProfile() { var opened: String? = null show(onProfileTap = { opened = it })
composeRule.onNodeWithContentDescription("alice.grain.social's avatar").performClick()
assertEquals("did:plc:alice", opened) }}