1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package social.grain
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.v2.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.json.Json
import okhttp3.OkHttpClient
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import social.grain.data.api.XrpcClient
import social.grain.data.api.getFeed
import social.grain.data.model.GrainGallery
import social.grain.data.model.GrainProfile
import social.grain.ui.components.GalleryCard
import social.grain.ui.theme.GrainTheme
import java.util.concurrent.TimeUnit
/**
* The "favorited by" line is viewer-scoped, so it is absent from every
* unauthenticated response and can't be observed from live data. These build
* the shape the appview returns and check the three phrasings.
*/
@RunWith(AndroidJUnit4::class)
class FacepileRenderTest {
@get:Rule val composeRule = createComposeRule()
private val client = XrpcClient(
"https://grain.social",
OkHttpClient.Builder().readTimeout(30, TimeUnit.SECONDS).build(),
Json { ignoreUnknownKeys = true; explicitNulls = false; coerceInputValues = true },
)
private fun gallery(favedBy: List<GrainProfile>): GrainGallery = runBlocking {
client.getFeed(feed = "recent", limit = 1).items.orEmpty().first()
.copy(favedByFollowing = favedBy)
}
private fun people(count: Int): List<GrainProfile> =
listOf("Alice", "Bob", "Carol").take(count).mapIndexed { index, name ->
GrainProfile(did = "did:plc:facepile$index", handle = "${name.lowercase()}.test", displayName = name)
}
private fun render(count: Int) {
val subject = gallery(people(count))
composeRule.setContent {
GrainTheme { Surface { GalleryCard(gallery = subject, modifier = Modifier.fillMaxWidth()) } }
}
composeRule.waitForIdle()
}
@Test
fun oneFavouriteNamesJustThatPerson() {
render(1)
composeRule.onNodeWithText("Favorited by Alice").assertExists()
}
@Test
fun twoFavouritesAreJoinedWithAnd() {
render(2)
composeRule.onNodeWithText("Favorited by Alice and Bob").assertExists()
}
@Test
fun threeOrMoreFallBackToAndOthers() {
render(3)
composeRule.onNodeWithText("Favorited by Alice, Bob and others you follow").assertExists()
}
@Test
fun noFavouritesRendersNoRow() {
val subject = gallery(emptyList())
composeRule.setContent {
GrainTheme { Surface { GalleryCard(gallery = subject, modifier = Modifier.fillMaxWidth()) } }
}
composeRule.waitForIdle()
composeRule.onNodeWithText("Favorited by", substring = true).assertDoesNotExist()
}
}