Skip to content

Commit b0e7a60

Browse files
committed
test: cover core screen states
1 parent 1a6dc6d commit b0e7a60

5 files changed

Lines changed: 176 additions & 17 deletions

File tree

‎app/src/androidTest/java/dev/typetype/android/feature/home/HomeScreenStateTest.kt‎

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ import androidx.compose.ui.semantics.SemanticsProperties
55
import androidx.compose.ui.test.SemanticsMatcher
66
import androidx.compose.ui.test.assertIsDisplayed
77
import androidx.compose.ui.test.junit4.v2.createComposeRule
8+
import androidx.compose.ui.test.onNodeWithContentDescription
89
import androidx.compose.ui.test.onNodeWithText
910
import androidx.compose.ui.test.performClick
11+
import androidx.compose.runtime.CompositionLocalProvider
12+
import dev.typetype.android.core.ui.components.LocalAnimatedStatePlayback
1013
import dev.typetype.android.core.ui.theme.TypeTypeTheme
1114
import dev.typetype.android.domain.feed.Video
1215
import dev.typetype.android.domain.library.HistoryItem
@@ -20,6 +23,26 @@ class HomeScreenStateTest {
2023
@get:Rule
2124
val composeRule = createComposeRule()
2225

26+
@Test
27+
fun initialLoadHasAnAccessibleState() {
28+
show(HomeState(isLoading = true))
29+
30+
composeRule.onNodeWithContentDescription("Loading").assertIsDisplayed()
31+
}
32+
33+
@Test
34+
fun fatalErrorKeepsTheRequestIdReviewable() {
35+
show(
36+
HomeState(
37+
errorMessage = "The home feed is unavailable",
38+
errorRequestId = "request-home",
39+
),
40+
)
41+
42+
composeRule.onNodeWithText("The home feed is unavailable").assertIsDisplayed()
43+
composeRule.onNodeWithText("Request request-home").assertIsDisplayed()
44+
}
45+
2346
@Test
2447
fun cachedContentStaysVisibleDuringRefresh() {
2548
show(
@@ -70,15 +93,17 @@ class HomeScreenStateTest {
7093
onPlayVideo: (String) -> Unit = {},
7194
) {
7295
composeRule.setContent {
73-
TypeTypeTheme {
74-
HomeContent(
75-
state = state,
76-
menuScope = emptyMenuScope(),
77-
onPlayVideo = onPlayVideo,
78-
onOpenChannel = {},
79-
onRetry = {},
80-
onLoadMore = {},
81-
)
96+
CompositionLocalProvider(LocalAnimatedStatePlayback provides false) {
97+
TypeTypeTheme {
98+
HomeContent(
99+
state = state,
100+
menuScope = emptyMenuScope(),
101+
onPlayVideo = onPlayVideo,
102+
onOpenChannel = {},
103+
onRetry = {},
104+
onLoadMore = {},
105+
)
106+
}
82107
}
83108
}
84109
}

‎app/src/androidTest/java/dev/typetype/android/feature/notifications/NotificationsScreenTest.kt‎

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import androidx.compose.ui.test.junit4.v2.createComposeRule
55
import androidx.compose.ui.test.onNodeWithContentDescription
66
import androidx.compose.ui.test.onNodeWithText
77
import androidx.compose.ui.test.performClick
8+
import androidx.compose.runtime.CompositionLocalProvider
9+
import dev.typetype.android.core.ui.components.LocalAnimatedStatePlayback
810
import dev.typetype.android.core.ui.theme.TypeTypeTheme
911
import dev.typetype.android.domain.feed.Video
1012
import dev.typetype.android.domain.notifications.NotificationItem
@@ -19,6 +21,27 @@ class NotificationsScreenTest {
1921
@get:Rule
2022
val composeRule = createComposeRule()
2123

24+
@Test
25+
fun initialLoadHasAnAccessibleState() {
26+
setScreen(NotificationsState(isLoading = true))
27+
28+
composeRule.onNodeWithContentDescription("Loading").assertIsDisplayed()
29+
}
30+
31+
@Test
32+
fun fatalErrorKeepsTheRequestIdReviewable() {
33+
setScreen(
34+
NotificationsState(
35+
isLoading = false,
36+
errorMessage = "Notifications are unavailable",
37+
errorRequestId = "request-notifications",
38+
),
39+
)
40+
41+
composeRule.onNodeWithText("Notifications are unavailable").assertIsDisplayed()
42+
composeRule.onNodeWithText("Request request-notifications").assertIsDisplayed()
43+
}
44+
2245
@Test
2346
fun emptyStateExplainsThatThereAreNoNotifications() {
2447
setScreen(NotificationsState(isLoading = false))
@@ -62,13 +85,15 @@ class NotificationsScreenTest {
6285
onAction: (NotificationsAction) -> Unit = {},
6386
) {
6487
composeRule.setContent {
65-
TypeTypeTheme {
66-
NotificationsScreen(
67-
state = state,
68-
onNavigateBack = {},
69-
onPlayVideo = onPlayVideo,
70-
onAction = onAction,
71-
)
88+
CompositionLocalProvider(LocalAnimatedStatePlayback provides false) {
89+
TypeTypeTheme {
90+
NotificationsScreen(
91+
state = state,
92+
onNavigateBack = {},
93+
onPlayVideo = onPlayVideo,
94+
onAction = onAction,
95+
)
96+
}
7297
}
7398
}
7499
}

‎app/src/androidTest/java/dev/typetype/android/feature/shorts/ShortsScreenTest.kt‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ class ShortsScreenTest {
2525
@get:Rule
2626
val composeRule = createComposeRule()
2727

28+
@Test
29+
fun initialLoadHasAnAccessibleState() {
30+
show(ShortsState(isLoading = true))
31+
32+
composeRule.onNodeWithContentDescription("Loading").assertIsDisplayed()
33+
}
34+
2835
@Test
2936
fun pagerShowsAPlayableShort() {
3037
val playedUrl = AtomicReference<String>()
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package dev.typetype.android.feature.subscriptions
2+
3+
import androidx.compose.runtime.CompositionLocalProvider
4+
import androidx.compose.ui.test.assertIsDisplayed
5+
import androidx.compose.ui.test.junit4.v2.createComposeRule
6+
import androidx.compose.ui.test.onNodeWithContentDescription
7+
import androidx.compose.ui.test.onNodeWithText
8+
import dev.typetype.android.core.ui.components.LocalAnimatedStatePlayback
9+
import dev.typetype.android.core.ui.theme.TypeTypeTheme
10+
import dev.typetype.android.domain.feed.Video
11+
import dev.typetype.android.feature.menu.VideoMenuScope
12+
import org.junit.Rule
13+
import org.junit.Test
14+
15+
class SubscriptionsScreenStateTest {
16+
@get:Rule
17+
val composeRule = createComposeRule()
18+
19+
@Test
20+
fun initialLoadHasAnAccessibleState() {
21+
show(SubscriptionsState(isLoading = true))
22+
23+
composeRule.onNodeWithContentDescription("Preparing subscriptions").assertIsDisplayed()
24+
}
25+
26+
@Test
27+
fun fatalErrorKeepsTheRequestIdReviewable() {
28+
show(
29+
SubscriptionsState(
30+
errorMessage = "Subscriptions are unavailable",
31+
errorRequestId = "request-subscriptions",
32+
),
33+
)
34+
35+
composeRule.onNodeWithText("Subscriptions are unavailable").assertIsDisplayed()
36+
composeRule.onNodeWithText("Request request-subscriptions").assertIsDisplayed()
37+
}
38+
39+
@Test
40+
fun emptyFeedHasAnExplicitState() {
41+
show(SubscriptionsState())
42+
43+
composeRule.onNodeWithText("Your subscriptions will appear here").assertIsDisplayed()
44+
}
45+
46+
@Test
47+
fun cachedContentStaysVisibleDuringRefresh() {
48+
show(
49+
SubscriptionsState(
50+
isLoading = true,
51+
videos = listOf(video()),
52+
),
53+
)
54+
55+
composeRule.onNodeWithText("Subscription video").assertIsDisplayed()
56+
}
57+
58+
private fun show(state: SubscriptionsState) {
59+
composeRule.setContent {
60+
CompositionLocalProvider(LocalAnimatedStatePlayback provides false) {
61+
TypeTypeTheme {
62+
SubscriptionsContent(
63+
state = state,
64+
visibleVideos = state.videos,
65+
onPlayVideo = {},
66+
onOpenChannel = {},
67+
onRetry = {},
68+
onLoadMore = {},
69+
menuScope = emptyMenuScope(),
70+
)
71+
}
72+
}
73+
}
74+
}
75+
76+
private fun emptyMenuScope() = VideoMenuScope(
77+
watchedUrls = emptySet(),
78+
blockedVideoUrls = emptySet(),
79+
blockedChannelUrls = emptySet(),
80+
blockedKeywords = emptySet(),
81+
favorites = emptySet(),
82+
watchLater = emptySet(),
83+
onAction = { _, _ -> },
84+
)
85+
86+
private fun video() = Video(
87+
id = "subscription",
88+
url = "https://video.example/subscription",
89+
title = "Subscription video",
90+
thumbnailUrl = "",
91+
uploaderName = "Channel",
92+
uploaderUrl = "https://channel.example/channel",
93+
uploaderAvatarUrl = "",
94+
uploaderVerified = false,
95+
durationSeconds = 180L,
96+
isLive = false,
97+
viewCount = 1L,
98+
uploadedAtMillis = 1L,
99+
isShortFormContent = false,
100+
shortDescription = null,
101+
)
102+
}

‎app/src/main/java/dev/typetype/android/feature/subscriptions/SubscriptionsScreen.kt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ fun SubscriptionsScreen(
118118
}
119119

120120
@Composable
121-
private fun SubscriptionsContent(
121+
internal fun SubscriptionsContent(
122122
state: SubscriptionsState,
123123
visibleVideos: List<dev.typetype.android.domain.feed.Video>,
124124
onPlayVideo: (videoUrl: String) -> Unit,

0 commit comments

Comments
 (0)