Skip to content

Commit fe40a13

Browse files
committed
test: HeadlinesPreviewContentTest
1 parent 99efbd2 commit fe40a13

File tree

3 files changed

+284
-14
lines changed

3 files changed

+284
-14
lines changed
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
package to.bitkit.ui.screens.widgets.headlines
2+
3+
import androidx.compose.ui.test.junit4.createComposeRule
4+
import androidx.compose.ui.test.onNodeWithTag
5+
import androidx.compose.ui.test.performClick
6+
import org.junit.Rule
7+
import org.junit.Test
8+
import to.bitkit.models.widget.ArticleModel
9+
import to.bitkit.models.widget.HeadlinePreferences
10+
import to.bitkit.ui.theme.AppThemeSurface
11+
12+
class HeadlinesPreviewContentTest {
13+
14+
@get:Rule
15+
val composeTestRule = createComposeRule()
16+
17+
private val mockArticle = ArticleModel(
18+
title = "Test Article Title",
19+
timeAgo = "2 hours ago",
20+
publisher = "Test Publisher",
21+
link = "https://example.com"
22+
)
23+
24+
private val mockHeadlinePreferences = HeadlinePreferences(
25+
showTime = true,
26+
showSource = true
27+
)
28+
29+
@Test
30+
fun testHeadlinesPreviewWithImplementedHeadlines() {
31+
// Arrange
32+
var closeClicked = false
33+
var backClicked = false
34+
var editClicked = false
35+
var deleteClicked = false
36+
var saveClicked = false
37+
38+
// Act
39+
composeTestRule.setContent {
40+
AppThemeSurface {
41+
HeadlinesPreviewContent(
42+
onClose = { closeClicked = true },
43+
onBack = { backClicked = true },
44+
onClickEdit = { editClicked = true },
45+
onClickDelete = { deleteClicked = true },
46+
onClickSave = { saveClicked = true },
47+
showWidgetTitles = true,
48+
isHeadlinesImplemented = true,
49+
headlinePreferences = mockHeadlinePreferences,
50+
article = mockArticle
51+
)
52+
}
53+
}
54+
55+
// Assert main elements exist
56+
composeTestRule.onNodeWithTag("headlines_preview_screen").assertExists()
57+
composeTestRule.onNodeWithTag("main_content").assertExists()
58+
59+
// Verify header elements
60+
composeTestRule.onNodeWithTag("header_row").assertExists()
61+
composeTestRule.onNodeWithTag("widget_title").assertExists()
62+
composeTestRule.onNodeWithTag("widget_icon").assertExists()
63+
composeTestRule.onNodeWithTag("widget_description").assertExists()
64+
65+
// Verify settings and preview section
66+
composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
67+
composeTestRule.onNodeWithTag("preview_label").assertExists()
68+
composeTestRule.onNodeWithTag("headline_card").assertExists()
69+
70+
// Verify buttons
71+
composeTestRule.onNodeWithTag("buttons_row").assertExists()
72+
composeTestRule.onNodeWithTag("delete_button").assertExists()
73+
composeTestRule.onNodeWithTag("save_button").assertExists()
74+
75+
// Test button clicks
76+
composeTestRule.onNodeWithTag("edit_settings_button").performClick()
77+
assert(editClicked)
78+
79+
composeTestRule.onNodeWithTag("delete_button").performClick()
80+
assert(deleteClicked)
81+
82+
composeTestRule.onNodeWithTag("save_button").performClick()
83+
assert(saveClicked)
84+
}
85+
86+
@Test
87+
fun testHeadlinesPreviewWithoutImplementedHeadlines() {
88+
// Arrange
89+
var closeClicked = false
90+
var backClicked = false
91+
var editClicked = false
92+
var deleteClicked = false
93+
var saveClicked = false
94+
95+
// Act
96+
composeTestRule.setContent {
97+
AppThemeSurface {
98+
HeadlinesPreviewContent(
99+
onClose = { closeClicked = true },
100+
onBack = { backClicked = true },
101+
onClickEdit = { editClicked = true },
102+
onClickDelete = { deleteClicked = true },
103+
onClickSave = { saveClicked = true },
104+
showWidgetTitles = false,
105+
isHeadlinesImplemented = false,
106+
headlinePreferences = mockHeadlinePreferences,
107+
article = mockArticle
108+
)
109+
}
110+
}
111+
112+
// Assert main elements exist
113+
composeTestRule.onNodeWithTag("headlines_preview_screen").assertExists()
114+
composeTestRule.onNodeWithTag("buttons_row").assertExists()
115+
116+
// Delete button should not exist when headlines are not implemented
117+
composeTestRule.onNodeWithTag("delete_button").assertDoesNotExist()
118+
composeTestRule.onNodeWithTag("save_button").assertExists()
119+
120+
// Test save button click
121+
composeTestRule.onNodeWithTag("save_button").performClick()
122+
assert(saveClicked)
123+
}
124+
125+
@Test
126+
fun testCustomHeadlinePreferences() {
127+
// Arrange
128+
val customPreferences = HeadlinePreferences(
129+
showTime = false,
130+
showSource = true
131+
)
132+
133+
// Act
134+
composeTestRule.setContent {
135+
AppThemeSurface {
136+
HeadlinesPreviewContent(
137+
onClose = {},
138+
onBack = {},
139+
onClickEdit = {},
140+
onClickDelete = {},
141+
onClickSave = {},
142+
showWidgetTitles = true,
143+
isHeadlinesImplemented = true,
144+
headlinePreferences = customPreferences,
145+
article = mockArticle
146+
)
147+
}
148+
}
149+
150+
// Assert that all elements still exist with custom preferences
151+
composeTestRule.onNodeWithTag("headlines_preview_screen").assertExists()
152+
composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
153+
composeTestRule.onNodeWithTag("headline_card").assertExists()
154+
}
155+
156+
@Test
157+
fun testAllElementsExist() {
158+
// Arrange
159+
composeTestRule.setContent {
160+
AppThemeSurface {
161+
HeadlinesPreviewContent(
162+
onClose = {},
163+
onBack = {},
164+
onClickEdit = {},
165+
onClickDelete = {},
166+
onClickSave = {},
167+
showWidgetTitles = true,
168+
isHeadlinesImplemented = true,
169+
headlinePreferences = mockHeadlinePreferences,
170+
article = mockArticle
171+
)
172+
}
173+
}
174+
175+
// Assert all tagged elements exist
176+
composeTestRule.onNodeWithTag("headlines_preview_screen").assertExists()
177+
composeTestRule.onNodeWithTag("main_content").assertExists()
178+
composeTestRule.onNodeWithTag("header_row").assertExists()
179+
composeTestRule.onNodeWithTag("widget_title").assertExists()
180+
composeTestRule.onNodeWithTag("widget_icon").assertExists()
181+
composeTestRule.onNodeWithTag("widget_description").assertExists()
182+
composeTestRule.onNodeWithTag("divider").assertExists()
183+
composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
184+
composeTestRule.onNodeWithTag("preview_label").assertExists()
185+
composeTestRule.onNodeWithTag("headline_card").assertExists()
186+
composeTestRule.onNodeWithTag("buttons_row").assertExists()
187+
composeTestRule.onNodeWithTag("delete_button").assertExists()
188+
composeTestRule.onNodeWithTag("save_button").assertExists()
189+
}
190+
191+
@Test
192+
fun testNavigationCallbacks() {
193+
// Arrange
194+
var closeClicked = false
195+
var backClicked = false
196+
197+
composeTestRule.setContent {
198+
AppThemeSurface {
199+
HeadlinesPreviewContent(
200+
onClose = { closeClicked = true },
201+
onBack = { backClicked = true },
202+
onClickEdit = {},
203+
onClickDelete = {},
204+
onClickSave = {},
205+
showWidgetTitles = true,
206+
isHeadlinesImplemented = true,
207+
headlinePreferences = mockHeadlinePreferences,
208+
article = mockArticle
209+
)
210+
}
211+
}
212+
}
213+
214+
@Test
215+
fun testWithMinimalHeadlinePreferences() {
216+
// Arrange
217+
val minimalPreferences = HeadlinePreferences(
218+
showTime = false,
219+
showSource = false
220+
)
221+
222+
// Act
223+
composeTestRule.setContent {
224+
AppThemeSurface {
225+
HeadlinesPreviewContent(
226+
onClose = {},
227+
onBack = {},
228+
onClickEdit = {},
229+
onClickDelete = {},
230+
onClickSave = {},
231+
showWidgetTitles = false,
232+
isHeadlinesImplemented = false,
233+
headlinePreferences = minimalPreferences,
234+
article = mockArticle
235+
)
236+
}
237+
}
238+
239+
// Assert core elements still exist
240+
composeTestRule.onNodeWithTag("headlines_preview_screen").assertExists()
241+
composeTestRule.onNodeWithTag("headline_card").assertExists()
242+
composeTestRule.onNodeWithTag("save_button").assertExists()
243+
composeTestRule.onNodeWithTag("delete_button").assertDoesNotExist()
244+
}
245+
}

app/src/main/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewScreen.kt

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import androidx.compose.runtime.getValue
1616
import androidx.compose.ui.Alignment
1717
import androidx.compose.ui.Modifier
1818
import androidx.compose.ui.graphics.Color
19+
import androidx.compose.ui.platform.testTag
1920
import androidx.compose.ui.res.painterResource
2021
import androidx.compose.ui.res.stringResource
2122
import androidx.compose.ui.text.AnnotatedString
@@ -82,42 +83,56 @@ fun HeadlinesPreviewContent(
8283
headlinePreferences: HeadlinePreferences,
8384
article: ArticleModel
8485
) {
85-
ScreenColumn {
86+
ScreenColumn(
87+
modifier = Modifier.testTag("headlines_preview_screen")
88+
) {
8689
AppTopBar(
8790
titleText = stringResource(R.string.widgets__widget__nav_title),
8891
onBackClick = onBack,
8992
actions = { CloseNavIcon(onClick = onClose) },
9093
)
9194

9295
Column(
93-
modifier = Modifier.padding(horizontal = 16.dp)
96+
modifier = Modifier
97+
.padding(horizontal = 16.dp)
98+
.testTag("main_content")
9499
) {
95100
Spacer(modifier = Modifier.height(26.dp))
96101

97102
Row(
98-
modifier = Modifier.fillMaxWidth(),
103+
modifier = Modifier
104+
.fillMaxWidth()
105+
.testTag("header_row"),
99106
verticalAlignment = Alignment.CenterVertically,
100107
horizontalArrangement = Arrangement.SpaceBetween
101108
) {
102109
Headline(
103110
text = AnnotatedString(stringResource(R.string.widgets__news__name)),
104-
modifier = Modifier.width(263.dp)
111+
modifier = Modifier
112+
.width(263.dp)
113+
.testTag("widget_title")
105114
)
106115
Icon(
107116
painter = painterResource(R.drawable.widget_newspaper),
108117
contentDescription = null,
109118
tint = Color.Unspecified,
110-
modifier = Modifier.size(64.dp)
119+
modifier = Modifier
120+
.size(64.dp)
121+
.testTag("widget_icon")
111122
)
112123
}
113124

114125
BodyM(
115126
text = stringResource(R.string.widgets__news__description),
116127
color = Colors.White64,
117-
modifier = Modifier.padding(vertical = 16.dp)
128+
modifier = Modifier
129+
.padding(vertical = 16.dp)
130+
.testTag("widget_description")
118131
)
119132

120-
HorizontalDivider()
133+
HorizontalDivider(
134+
modifier = Modifier.testTag("divider")
135+
)
121136

122137
SettingsButtonRow(
123138
title = stringResource(R.string.widgets__widget__edit),
@@ -128,19 +143,24 @@ fun HeadlinesPreviewContent(
128143
stringResource(R.string.widgets__widget__edit_custom)
129144
}
130145
),
131-
onClick = onClickEdit
146+
onClick = onClickEdit,
147+
modifier = Modifier.testTag("edit_settings_button")
132148
)
133149

134150
Spacer(modifier = Modifier.weight(1f))
135151

136152
Text13Up(
137153
stringResource(R.string.common__preview),
138154
color = Colors.White64,
139-
modifier = Modifier.padding(vertical = 16.dp)
155+
modifier = Modifier
156+
.padding(vertical = 16.dp)
157+
.testTag("preview_label")
140158
)
141159

142160
HeadlineCard(
143-
modifier = Modifier.fillMaxWidth(),
161+
modifier = Modifier
162+
.fillMaxWidth()
163+
.testTag("headline_card"),
144164
showWidgetTitle = showWidgetTitles,
145165
showTime = headlinePreferences.showTime,
146166
showSource = headlinePreferences.showSource,
@@ -153,21 +173,26 @@ fun HeadlinesPreviewContent(
153173
Row(
154174
modifier = Modifier
155175
.padding(vertical = 21.dp)
156-
.fillMaxWidth(),
176+
.fillMaxWidth()
177+
.testTag("buttons_row"),
157178
horizontalArrangement = Arrangement.spacedBy(16.dp)
158179
) {
159180
if (isHeadlinesImplemented) {
160181
SecondaryButton(
161182
text = stringResource(R.string.common__delete),
162-
modifier = Modifier.weight(1f),
183+
modifier = Modifier
184+
.weight(1f)
185+
.testTag("delete_button"),
163186
fullWidth = false,
164187
onClick = onClickDelete
165188
)
166189
}
167190

168191
PrimaryButton(
169192
text = stringResource(R.string.common__save),
170-
modifier = Modifier.weight(1f),
193+
modifier = Modifier
194+
.weight(1f)
195+
.testTag("save_button"),
171196
fullWidth = false,
172197
onClick = onClickSave
173198
)

app/src/main/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class HeadlinesViewModel @Inject constructor(
116116
timeAgo = "21 minutes ago",
117117
title = "How Bitcoin changed El Salvador in more ways",
118118
publisher = "bitcoinmagazine.com",
119-
link = "bitcoinmagazine.com"
119+
link = "https://bitcoinmagazine.com"
120120
)
121121
}
122122
}

0 commit comments

Comments
 (0)