Skip to content

Commit

Permalink
[AND-304] Add snapshot tests for ThreadList and related components. (#…
Browse files Browse the repository at this point in the history
…5610)

* [AND-304] Add snapshot tests for ThreadList and related components.

* [AND-304] Update CHANGELOG.md.

---------

Co-authored-by: PetarVelikov <[email protected]>
  • Loading branch information
VelikovPetar and PetarVelikov authored Feb 4, 2025
1 parent efde80e commit 649148b
Show file tree
Hide file tree
Showing 17 changed files with 391 additions and 81 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
- Introduce `ChatComponentFactory` for easier channel components customization. Initially supporting channel stateless components. [#5571](https://github.com/GetStream/stream-chat-android/pull/5571)
- Deprecate `MessageContentFactory` in favor of `ChatComponentFactory`. [#5571](https://github.com/GetStream/stream-chat-android/pull/5571)
- Create snapshot tests for messages stateless components. [#5578](https://github.com/GetStream/stream-chat-android/pull/5578)
- Create snapshot tests for thread list components. [#5610](https://github.com/GetStream/stream-chat-android/pull/5610)
- Create message stateless component factories and refactor to have a single component factory object. [#5593](https://github.com/GetStream/stream-chat-android/pull/5593)
- Create message list header component factories. [#5599](https://github.com/GetStream/stream-chat-android/pull/5599)
- Create message footer status indicator stateless component factories. [#5598](https://github.com/GetStream/stream-chat-android/pull/5598)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,13 @@ import io.getstream.chat.android.compose.state.OnlineIndicatorAlignment
import io.getstream.chat.android.compose.ui.components.Timestamp
import io.getstream.chat.android.compose.ui.components.avatar.DefaultOnlineIndicator
import io.getstream.chat.android.compose.ui.components.channels.UnreadCountIndicator
import io.getstream.chat.android.compose.ui.theme.ChatPreviewTheme
import io.getstream.chat.android.compose.ui.theme.ChatTheme
import io.getstream.chat.android.models.Channel
import io.getstream.chat.android.models.ChannelUserRead
import io.getstream.chat.android.models.Message
import io.getstream.chat.android.models.Thread
import io.getstream.chat.android.models.ThreadParticipant
import io.getstream.chat.android.models.User
import java.util.Date
import io.getstream.chat.android.previewdata.PreviewThreadData

/**
* The basic Thread item, showing information about the Thread title, parent message, last reply and number of unread
Expand Down Expand Up @@ -264,47 +263,11 @@ private fun formatMessage(message: Message) =
@Composable
@Preview
private fun ThreadItemPreview() {
ChatTheme {
ChatPreviewTheme {
Surface {
val user1 = User(id = "uid1", name = "User 1")
val user2 = User(id = "uid2", name = "User 2")
val thread = Thread(
activeParticipantCount = 2,
cid = "cid",
channel = Channel(),
parentMessageId = "pmid1",
parentMessage = Message(
id = "pmid1",
text = "Hey everyone, who's up for a group ride this Saturday morning?",
),
createdByUserId = "uid2",
createdBy = user2,
participantCount = 2,
threadParticipants = listOf(
ThreadParticipant(user1),
ThreadParticipant(user2),
),
lastMessageAt = Date(),
createdAt = Date(),
updatedAt = Date(),
deletedAt = null,
title = "Group ride preparation and discussion",
latestReplies = listOf(
Message(id = "mid1", text = "See you all there, stay safe on the roads!", user = user1),
),
read = listOf(
ChannelUserRead(
user = user2,
lastReceivedEventDate = Date(),
unreadMessages = 3,
lastRead = Date(),
lastReadMessageId = null,
),
),
)
ThreadItem(
thread = thread,
currentUser = user2,
thread = PreviewThreadData.thread,
currentUser = PreviewThreadData.participant2,
onThreadClick = {},
)
}
Expand All @@ -314,7 +277,7 @@ private fun ThreadItemPreview() {
@Composable
@Preview
private fun DefaultThreadTitlePreview() {
ChatTheme {
ChatPreviewTheme {
Surface {
DefaultThreadTitle(
channel = Channel(
Expand All @@ -331,7 +294,7 @@ private fun DefaultThreadTitlePreview() {
@Composable
@Preview
private fun DefaultUnreadCountContentPreview() {
ChatTheme {
ChatPreviewTheme {
Row {
DefaultUnreadCountContent(unreadCount = 17)
}
Expand All @@ -341,7 +304,7 @@ private fun DefaultUnreadCountContentPreview() {
@Composable
@Preview
private fun ThreadParentMessageContentPreview() {
ChatTheme {
ChatPreviewTheme {
Row {
val parentMessage = Message(
id = "message1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,44 +56,44 @@ public fun UnreadThreadsBanner(
modifier: Modifier = Modifier,
onClick: (() -> Unit)? = null,
) {
if (unreadThreads <= 0) {
// Don't show if there are no new threads
return
}
val clickableModifier = if (onClick != null) {
Modifier.clickable { onClick() }
} else {
Modifier
}
Row(
modifier = modifier
.fillMaxWidth()
.heightIn(min = 52.dp)
.background(ChatTheme.colors.textHighEmphasis, RoundedCornerShape(16.dp))
.clip(RoundedCornerShape(16.dp))
.then(clickableModifier)
.padding(start = 16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
) {
val text = pluralStringResource(R.plurals.stream_compose_thread_list_new_threads, unreadThreads, unreadThreads)
Text(
modifier = Modifier.weight(1f),
text = text,
fontSize = 16.sp,
color = ChatTheme.colors.barsBackground,
lineHeight = 20.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
IconButton(
onClick = {},
if (unreadThreads > 0) {
val clickableModifier = if (onClick != null) {
Modifier.clickable { onClick() }
} else {
Modifier
}
Row(
modifier = modifier
.fillMaxWidth()
.heightIn(min = 52.dp)
.background(ChatTheme.colors.textHighEmphasis, RoundedCornerShape(16.dp))
.clip(RoundedCornerShape(16.dp))
.then(clickableModifier)
.padding(start = 16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
) {
Icon(
painter = painterResource(id = R.drawable.stream_compose_ic_union),
contentDescription = "Reload threads",
tint = ChatTheme.colors.barsBackground,
val text =
pluralStringResource(R.plurals.stream_compose_thread_list_new_threads, unreadThreads, unreadThreads)
Text(
modifier = Modifier.weight(1f),
text = text,
fontSize = 16.sp,
color = ChatTheme.colors.barsBackground,
lineHeight = 20.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
IconButton(
onClick = {},
) {
Icon(

painter = painterResource(id = R.drawable.stream_compose_ic_union),
contentDescription = "Reload threads",
tint = ChatTheme.colors.barsBackground,
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2014-2025 Stream.io Inc. All rights reserved.
*
* Licensed under the Stream License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.getstream.chat.android.compose.ui.threads

import app.cash.paparazzi.DeviceConfig
import app.cash.paparazzi.Paparazzi
import io.getstream.chat.android.compose.ui.SnapshotTest
import io.getstream.chat.android.previewdata.PreviewThreadData
import org.junit.Rule
import org.junit.Test

internal class ThreadItemTest : SnapshotTest {

@get:Rule
override val paparazzi = Paparazzi(deviceConfig = DeviceConfig.PIXEL_2)

@Test
fun threadItem() {
snapshotWithDarkMode {
ThreadItem(
thread = PreviewThreadData.thread,
currentUser = PreviewThreadData.participant2,
onThreadClick = { },
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2014-2025 Stream.io Inc. All rights reserved.
*
* Licensed under the Stream License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.getstream.chat.android.compose.ui.threads

import androidx.compose.foundation.background
import androidx.compose.ui.Modifier
import app.cash.paparazzi.DeviceConfig
import app.cash.paparazzi.Paparazzi
import io.getstream.chat.android.compose.ui.SnapshotTest
import io.getstream.chat.android.compose.ui.theme.ChatTheme
import io.getstream.chat.android.previewdata.PreviewThreadData
import io.getstream.chat.android.ui.common.state.threads.ThreadListState
import org.junit.Rule
import org.junit.Test

internal class ThreadListTest : SnapshotTest {

@get:Rule
override val paparazzi = Paparazzi(deviceConfig = DeviceConfig.PIXEL_2)

@Test
fun `loading threads`() {
snapshotWithDarkMode {
ThreadList(
modifier = Modifier.background(ChatTheme.colors.appBackground),
state = ThreadListState(
threads = emptyList(),
isLoading = true,
isLoadingMore = false,
unseenThreadsCount = 0,
),
onUnreadThreadsBannerClick = {},
onThreadClick = { },
onLoadMore = {},
)
}
}

@Test
fun `empty threads`() {
snapshotWithDarkMode {
ThreadList(
modifier = Modifier.background(ChatTheme.colors.appBackground),
state = ThreadListState(
threads = emptyList(),
isLoading = false,
isLoadingMore = false,
unseenThreadsCount = 0,
),
onUnreadThreadsBannerClick = {},
onThreadClick = { },
onLoadMore = {},
)
}
}

@Test
fun `loaded threads`() {
snapshotWithDarkMode {
ThreadList(
modifier = Modifier.background(ChatTheme.colors.appBackground),
state = ThreadListState(
threads = PreviewThreadData.threadList,
isLoading = false,
isLoadingMore = false,
unseenThreadsCount = 0,
),
onUnreadThreadsBannerClick = {},
onThreadClick = { },
onLoadMore = {},
)
}
}

@Test
fun `loaded threads with unread banner`() {
snapshotWithDarkMode {
ThreadList(
modifier = Modifier.background(ChatTheme.colors.appBackground),
state = ThreadListState(
threads = PreviewThreadData.threadList,
isLoading = false,
isLoadingMore = false,
unseenThreadsCount = 1,
),
onUnreadThreadsBannerClick = {},
onThreadClick = { },
onLoadMore = {},
)
}
}

@Test
fun `loading more threads`() {
snapshotWithDarkMode {
ThreadList(
modifier = Modifier.background(ChatTheme.colors.appBackground),
state = ThreadListState(
threads = PreviewThreadData.threadList,
isLoading = false,
isLoadingMore = true,
unseenThreadsCount = 0,
),
onUnreadThreadsBannerClick = {},
onThreadClick = { },
onLoadMore = {},
)
}
}
}
Loading

0 comments on commit 649148b

Please sign in to comment.