Skip to content

Commit 3909f95

Browse files
authored
Increase code coverage of compose module (#5932)
* Add Turbine library to compose module * Add unit tests for ChannelHeaderViewModel * Add unit tests for ChannelAttachmentsViewModel * Add unit tests for ChannelInfoMemberViewModel * Add unit tests for ChannelInfoViewModel * Add unit tests for ChannelAttachmentsViewModelFactory * Add unit tests for ChannelHeaderViewModelFactory * Add unit tests for ChannelInfoViewModelFactory * Add unit tests for ChannelInfoMemberViewModelFactory * Add unit tests for ChannelViewModelFactory * Add unit tests and preview for GiphyAttachmentContent * Add previews and unit tests for media attachment content * Add unit tests for PinnedMessageListViewModel * Add unit tests for MentionListViewModel * Add unit tests for MentionListViewModelFactory * Add unit tests for MessagesViewModelFactory * Add unit tests for ThreadsViewModelFactory and ThreadListViewModel * Add unit tests for MentionSuggestionList * Remove the fixed height modifier in `FileUploadItem` * Add unit tests for CommandSuggestionList * Integrate Kover for better code coverage reporting * Update snapshots * Increase code coverage of ChannelsScreen * Add unit tests for PinnedMessagesScreen and update PinnedMessageListState defaults * Add unit tests for MessageComposerScreen * Add unit tests for ChatsScreen * Increase coverage of CopyToClipboardHandlerImpl * Increase code coverage of ChannelsScreen * Add unit tests for ChatsScreen * Add unit tests for MessagesScreen * Deprecate AudioWaveVSeekbar component * Add unit tests and preview for AudioWaveVSeekbar component * Add unit tests for MessageModerationDialog * Add previews and snapshot tests for MessageComposerRecordingContent * Rename SuggestionLazyList to MentionSuggestionLazyList for clarity * Refactor PinnedMessageListState to use default values and update tests * Refactor view models to use property accessors for controller and state * code review * Log only failed tests * Remove MessageComposerCommandSuggestionListHeader component factory
1 parent 249081b commit 3909f95

File tree

80 files changed

+2721
-353
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+2721
-353
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,12 @@
6969
### 🐞 Fixed
7070

7171
### ⬆️ Improved
72+
- Remove the fixed height modifier in `FileUploadItem`. [#5932](https://github.com/GetStream/stream-chat-android/pull/5932)
7273

7374
### ✅ Added
7475

7576
### ⚠️ Changed
77+
- Deprecate unused component `AudioWaveVSeekbar`. [#5932](https://github.com/GetStream/stream-chat-android/pull/5932)
7678

7779
### ❌ Removed
7880

DEPRECATIONS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ This document lists deprecated constructs in the SDK, with their expected time
44

55
| API / Feature | Deprecated (warning) | Deprecated (error) | Removed | Notes |
66
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------|-----------------------|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
7+
| `AudioWaveVSeekbar`<br/>*compose* | 2025.09.22 ⌛ | | | |
78
| `AttachmentType.LINK` constant | 2025.09.08 ⌛ | | | This property has been deprecated. The attachment of type 'LINK' is not officially supported, and Attachment.type can never have a value equal to "link". |
89
| `Attachment.isLink()` method | 2025.09.08 ⌛ | | | This method has been deprecated. The attachment of type 'LINK' is not officially supported, and Attachment.type can never have a value equal to "link". |
910
| `StreamColors.linkBackground` property | 2025.08.12 ⌛ | | | This property has been deprecated. Please use `MessageTheme.linkBackgroundColor` instead. |

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ plugins {
2323
alias(libs.plugins.shot) apply false
2424
alias(libs.plugins.androidx.navigation) apply false
2525
alias(libs.plugins.sonarqube) apply false
26+
alias(libs.plugins.kover) apply false
2627
id("io.getstream.chat.UnitTestsPlugin")
2728
id("io.getstream.chat.ReleasePlugin")
2829
id("io.getstream.chat.ChangelogReleaseSectionPlugin")

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ timber = "5.0.1"
8787
turbine = "1.2.0"
8888
work = "2.9.1"
8989
playServicesLocation = "21.3.0"
90+
kover = "0.9.2"
9091

9192
[libraries]
9293
allure-kotlin-model = { module = "io.qameta.allure:allure-kotlin-model", version.ref = "allureKotlin"}
@@ -244,3 +245,4 @@ shot = { id = "shot", version.ref = "shot"}
244245
sonarqube = { id = "org.sonarqube", version.ref = "sonarqube"}
245246
spotless = { id = "com.diffplug.spotless", version.ref = "spotless"}
246247
paparazzi = { id = "app.cash.paparazzi", version.ref = "paparazzi"}
248+
kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover"}

scripts/coverage.gradle

Lines changed: 57 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,72 @@
1-
if (!rootProject.ext.sonar.ignoreModules.contains(name)) {
2-
apply plugin: 'jacoco'
1+
if (!rootProject.ext.sonar.ignoreModules.contains(name) && file("src/test").exists()) {
2+
apply plugin: "org.jetbrains.kotlinx.kover"
33
apply plugin: "org.sonarqube"
44

5-
def isCore = (name == 'stream-chat-android-core')
6-
def isCompose = (name == 'stream-chat-android-compose')
7-
def testTask = isCore ? "test" : isCompose ? "verifyPaparazziDebug" : "testDebugUnitTest"
8-
def jacocoResults = "${buildDir}/reports/jacoco/report.xml"
9-
10-
if (hasProperty('android')) {
11-
android {
12-
buildTypes {
13-
debug {
14-
testCoverageEnabled = true
15-
enableUnitTestCoverage = true
16-
enableAndroidTestCoverage true
5+
afterEvaluate {
6+
def isAndroidModule = plugins.hasPlugin("com.android.library") || plugins.hasPlugin("com.android.application")
7+
def hasPaparazziPlugin = plugins.hasPlugin("app.cash.paparazzi")
8+
9+
if (isAndroidModule) {
10+
android {
11+
buildTypes {
12+
debug {
13+
testCoverageEnabled = true
14+
enableUnitTestCoverage = true
15+
enableAndroidTestCoverage true
16+
}
1717
}
1818
}
1919
}
20-
}
2120

22-
afterEvaluate {
23-
tasks.withType(Test).configureEach {
24-
jacoco.includeNoLocationClasses = true
25-
jacoco.excludes = ['jdk.internal.*']
26-
}
21+
def testTaskName = isAndroidModule
22+
? (hasPaparazziPlugin ? "verifyPaparazziDebug" : "testDebugUnitTest")
23+
: "test"
2724

28-
tasks.register("testCoverage", JacocoReport) {
29-
dependsOn testTask
25+
tasks.register("testCoverage") {
26+
group = "verification"
27+
description = "Run module-specific tests and generate coverage reports"
28+
dependsOn(testTaskName)
3029

31-
reports {
32-
xml.required.set(true)
33-
xml.outputLocation.set(file(jacocoResults))
30+
if (isAndroidModule) {
31+
dependsOn "koverXmlReportDebug", "koverHtmlReportDebug"
32+
} else {
33+
dependsOn "koverXmlReport", "koverHtmlReport"
3434
}
35+
}
3536

36-
executionData.setFrom(fileTree(dir: buildDir, includes: [
37-
"outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec",
38-
"jacoco/test.exec"
39-
]))
40-
41-
def sources = isCore ? sourceSets.main.java.srcDirs : android.sourceSets.main.java.srcDirs
42-
sourceDirectories.setFrom(files(sources))
43-
classDirectories.setFrom(files([
44-
fileTree(
45-
dir: "${buildDir}/tmp/kotlin-classes/debug",
46-
excludes: rootProject.ext.sonar.excludeFilter
47-
),
48-
fileTree(
49-
dir: "${buildDir}/classes/kotlin/main",
50-
excludes: rootProject.ext.sonar.excludeFilter
51-
)
52-
]))
37+
kover {
38+
reports {
39+
verify {
40+
warningInsteadOfFailure = true
41+
}
42+
filters {
43+
excludes {
44+
// Existing sonar excludes
45+
classes(rootProject.ext.sonar.excludeFilter as String[])
46+
// Exclude Compose-generated singletons
47+
classes("*ComposableSingletons*")
48+
// Exclude Compose previews
49+
annotatedBy("androidx.compose.ui.tooling.preview.Preview")
50+
}
51+
}
52+
}
5353
}
54-
}
5554

56-
sonarqube {
57-
properties {
58-
property "sonar.junit.reportPaths", "${buildDir}/test-results/${testTask}"
59-
property "sonar.coverage.jacoco.xmlReportPaths", jacocoResults
55+
sonarqube {
56+
properties {
57+
def mainSources = []
58+
if (file("src/main/java").exists()) mainSources += "src/main/java"
59+
if (file("src/main/kotlin").exists()) mainSources += "src/main/kotlin"
60+
61+
property "sonar.sources", mainSources.join(",")
62+
63+
def xmlReportPaths = isAndroidModule
64+
? "$buildDir/reports/kover/reportDebug.xml"
65+
: "$buildDir/reports/kover/report.xml"
66+
67+
property "sonar.junit.reportPaths", "${buildDir}/test-results/${testTaskName}"
68+
property "sonar.coverage.jacoco.xmlReportPaths", xmlReportPaths
69+
}
6070
}
6171
}
6272
}

scripts/sonar.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ ext.sonar = [
1313
'stream-chat-android-ui-components-sample',
1414
'stream-chat-android-client-test',
1515
'stream-chat-android-ui-uitests',
16-
'metrics'
16+
'stream-chat-android-metrics'
1717
],
1818
excludeFilter : [
1919
'**/test/**',

stream-chat-android-compose/api/stream-chat-android-compose.api

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,15 @@ public final class io/getstream/chat/android/compose/ui/attachments/content/Comp
513513
public final fun getLambda-1$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
514514
}
515515

516+
public final class io/getstream/chat/android/compose/ui/attachments/content/ComposableSingletons$GiphyAttachmentContentKt {
517+
public static final field INSTANCE Lio/getstream/chat/android/compose/ui/attachments/content/ComposableSingletons$GiphyAttachmentContentKt;
518+
public static field lambda-1 Lkotlin/jvm/functions/Function2;
519+
public static field lambda-2 Lkotlin/jvm/functions/Function2;
520+
public fun <init> ()V
521+
public final fun getLambda-1$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
522+
public final fun getLambda-2$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
523+
}
524+
516525
public final class io/getstream/chat/android/compose/ui/attachments/content/ComposableSingletons$ImageAttachmentPreviewContentKt {
517526
public static final field INSTANCE Lio/getstream/chat/android/compose/ui/attachments/content/ComposableSingletons$ImageAttachmentPreviewContentKt;
518527
public static field lambda-1 Lkotlin/jvm/functions/Function2;
@@ -535,9 +544,17 @@ public final class io/getstream/chat/android/compose/ui/attachments/content/Comp
535544
public static final field INSTANCE Lio/getstream/chat/android/compose/ui/attachments/content/ComposableSingletons$MediaAttachmentContentKt;
536545
public static field lambda-1 Lkotlin/jvm/functions/Function3;
537546
public static field lambda-2 Lkotlin/jvm/functions/Function3;
547+
public static field lambda-3 Lkotlin/jvm/functions/Function2;
548+
public static field lambda-4 Lkotlin/jvm/functions/Function2;
549+
public static field lambda-5 Lkotlin/jvm/functions/Function2;
550+
public static field lambda-6 Lkotlin/jvm/functions/Function2;
538551
public fun <init> ()V
539552
public final fun getLambda-1$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function3;
540553
public final fun getLambda-2$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function3;
554+
public final fun getLambda-3$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
555+
public final fun getLambda-4$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
556+
public final fun getLambda-5$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
557+
public final fun getLambda-6$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
541558
}
542559

543560
public final class io/getstream/chat/android/compose/ui/attachments/content/ComposableSingletons$MediaAttachmentPreviewContentKt {
@@ -2036,8 +2053,10 @@ public final class io/getstream/chat/android/compose/ui/components/suggestions/c
20362053
public final class io/getstream/chat/android/compose/ui/components/suggestions/commands/ComposableSingletons$CommandSuggestionListKt {
20372054
public static final field INSTANCE Lio/getstream/chat/android/compose/ui/components/suggestions/commands/ComposableSingletons$CommandSuggestionListKt;
20382055
public static field lambda-1 Lkotlin/jvm/functions/Function2;
2056+
public static field lambda-2 Lkotlin/jvm/functions/Function2;
20392057
public fun <init> ()V
20402058
public final fun getLambda-1$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
2059+
public final fun getLambda-2$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
20412060
}
20422061

20432062
public final class io/getstream/chat/android/compose/ui/components/suggestions/mentions/ComposableSingletons$MentionSuggestionItemKt {
@@ -2053,6 +2072,13 @@ public final class io/getstream/chat/android/compose/ui/components/suggestions/m
20532072
public final fun getLambda-4$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function3;
20542073
}
20552074

2075+
public final class io/getstream/chat/android/compose/ui/components/suggestions/mentions/ComposableSingletons$MentionSuggestionListKt {
2076+
public static final field INSTANCE Lio/getstream/chat/android/compose/ui/components/suggestions/mentions/ComposableSingletons$MentionSuggestionListKt;
2077+
public static field lambda-1 Lkotlin/jvm/functions/Function2;
2078+
public fun <init> ()V
2079+
public final fun getLambda-1$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
2080+
}
2081+
20562082
public final class io/getstream/chat/android/compose/ui/components/suggestions/mentions/MentionSuggestionItemKt {
20572083
public static final fun MentionSuggestionItem (Lio/getstream/chat/android/models/User;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Landroidx/compose/runtime/Composer;II)V
20582084
}
@@ -2484,9 +2510,15 @@ public final class io/getstream/chat/android/compose/ui/messages/composer/intern
24842510
public static final field INSTANCE Lio/getstream/chat/android/compose/ui/messages/composer/internal/ComposableSingletons$DefaultMessageComposerRecordingContentKt;
24852511
public static field lambda-1 Lkotlin/jvm/functions/Function2;
24862512
public static field lambda-2 Lkotlin/jvm/functions/Function2;
2513+
public static field lambda-3 Lkotlin/jvm/functions/Function2;
2514+
public static field lambda-4 Lkotlin/jvm/functions/Function2;
2515+
public static field lambda-5 Lkotlin/jvm/functions/Function2;
24872516
public fun <init> ()V
24882517
public final fun getLambda-1$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
24892518
public final fun getLambda-2$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
2519+
public final fun getLambda-3$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
2520+
public final fun getLambda-4$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
2521+
public final fun getLambda-5$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
24902522
}
24912523

24922524
public final class io/getstream/chat/android/compose/ui/messages/composer/internal/DefaultMessageComposerRecordingContentKt {
@@ -5014,8 +5046,8 @@ public final class io/getstream/chat/android/compose/viewmodel/threads/ThreadLis
50145046
public final class io/getstream/chat/android/compose/viewmodel/threads/ThreadsViewModelFactory : androidx/lifecycle/ViewModelProvider$Factory {
50155047
public static final field $stable I
50165048
public fun <init> ()V
5017-
public fun <init> (III)V
5018-
public synthetic fun <init> (IIIILkotlin/jvm/internal/DefaultConstructorMarker;)V
5049+
public fun <init> (IIILio/getstream/chat/android/client/ChatClient;)V
5050+
public synthetic fun <init> (IIILio/getstream/chat/android/client/ChatClient;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
50195051
public fun create (Ljava/lang/Class;)Landroidx/lifecycle/ViewModel;
50205052
}
50215053

stream-chat-android-compose/build.gradle.kts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ android {
3131

3232
resourcePrefix = "stream_compose_"
3333

34+
testOptions {
35+
unitTests {
36+
isIncludeAndroidResources = true
37+
unitTests.isReturnDefaultValues = true
38+
}
39+
}
40+
3441
buildTypes {
3542
getByName("release") {
3643
isMinifyEnabled = false
@@ -110,6 +117,7 @@ dependencies {
110117
testImplementation(project(":stream-chat-android-test"))
111118
testImplementation(testFixtures(project(":stream-chat-android-core")))
112119
testImplementation(project(":stream-chat-android-previewdata"))
120+
testImplementation(libs.androidx.compose.ui.test.junit4)
113121
testImplementation(libs.junit.jupiter.api)
114122
testImplementation(libs.junit.jupiter.params)
115123
testRuntimeOnly(libs.junit.jupiter.engine)
@@ -118,6 +126,8 @@ dependencies {
118126
testImplementation(libs.kluent)
119127
testImplementation(libs.mockito)
120128
testImplementation(libs.mockito.kotlin)
129+
testImplementation(libs.turbine)
130+
testImplementation(libs.robolectric)
121131

122132
detektPlugins(libs.detekt.formatting)
123133

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/FileUploadContent.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.Column
2424
import androidx.compose.foundation.layout.Row
2525
import androidx.compose.foundation.layout.Spacer
2626
import androidx.compose.foundation.layout.fillMaxWidth
27-
import androidx.compose.foundation.layout.height
2827
import androidx.compose.foundation.layout.padding
2928
import androidx.compose.foundation.layout.size
3029
import androidx.compose.material3.Surface
@@ -105,7 +104,6 @@ public fun FileUploadItem(
105104
Row(
106105
Modifier
107106
.fillMaxWidth()
108-
.height(50.dp)
109107
.padding(vertical = 8.dp, horizontal = 8.dp),
110108
verticalAlignment = Alignment.CenterVertically,
111109
) {

0 commit comments

Comments
 (0)