cometchat-android-v6-testing — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited cometchat-android-v6-testing (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Ground truth:com.cometchat:chatuikit-{compose,kotlin}-android:6.x(+calls-sdk-android:5.x) — resolved AAR (javap) +ui-kit/android/v6. Official docs: https://www.cometchat.com/docs/ui-kit/android/v6/overview · Docs MCP:claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp(or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.
Companion skills: cometchat-android-v6-extensions (ViewModel/DataSource architecture), cometchat-android-v6-compose-components, cometchat-android-v6-kotlin-components
Test CometChat UIKit v6 components and ViewModels — unit tests for the shared core module, Compose UI tests, Espresso tests for Views, and end-to-end tests with Maestro.
cometchat-android-v6-troubleshooting)cometchat-*-components)From chatuikit-compose/build.gradle.kts:
dependencies {
// Unit testing
testImplementation("junit:junit:4.13.2")
testImplementation("io.kotest:kotest-runner-junit5:5.x")
testImplementation("io.kotest:kotest-assertions-core:5.x")
testImplementation("io.kotest:kotest-property:5.x")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.x")
testImplementation("androidx.arch.core:core-testing:2.x")
testImplementation("androidx.lifecycle:lifecycle-runtime-testing:2.x")
testImplementation("org.mockito:mockito-core:5.x")
testImplementation("org.mockito.kotlin:mockito-kotlin:5.x")
// Android instrumented testing
androidTestImplementation("androidx.test.ext:junit:1.x")
androidTestImplementation("androidx.test.espresso:espresso-core:3.x")
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
androidTestImplementation(platform("androidx.compose:compose-bom:2024.x.x"))
// Debug-only Compose tooling
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}Enable JUnit Platform for Kotest:
android {
testOptions {
unitTests.all {
it.useJUnitPlatform()
}
}
}ViewModels live in chatuikit-core and are shared across both stacks. Test them with coroutines-test and Mockito:
import kotlinx.coroutines.test.runTest
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
class CometChatConversationsViewModelTest {
@Test
fun `loadConversations emits success state`() = runTest {
val mockDataSource = mock<ConversationListDataSource>()
// Setup mock responses...
val viewModel = CometChatConversationsViewModel(/* inject mocks */)
// Collect state and assert
viewModel.uiState.test {
val state = awaitItem()
// Assert state is success with expected data
}
}
}import com.cometchat.uikit.core.events.CometChatEvents
import com.cometchat.uikit.core.events.CometChatMessageEvent
@Test
fun `emitting message event is received by collector`() = runTest {
val events = mutableListOf<CometChatMessageEvent>()
val job = launch {
CometChatEvents.messageEvents.collect { events.add(it) }
}
CometChatEvents.emitMessageEvent(
CometChatMessageEvent.MessageSent(mockMessage, MessageStatus.SUCCESS)
)
advanceUntilIdle()
assertEquals(1, events.size)
job.cancel()
}import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
class CometChatConversationsTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun conversationsList_displaysTitle() {
composeTestRule.setContent {
CometChatTheme {
CometChatConversations()
}
}
// Assert UI elements
composeTestRule.onNodeWithText("Chats").assertExists()
}
@Test
fun conversationItem_clickNavigates() {
var clickedConversation: Conversation? = null
composeTestRule.setContent {
CometChatTheme {
CometChatConversations(
onItemClick = { clickedConversation = it }
)
}
}
// Interact and assert
// composeTestRule.onNodeWithText("User Name").performClick()
// assertNotNull(clickedConversation)
}
}import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.rules.ActivityScenarioRule
class ConversationsActivityTest {
@get:Rule
val activityRule = ActivityScenarioRule(ConversationsActivity::class.java)
@Test
fun conversationsList_isDisplayed() {
onView(withId(R.id.conversations))
.check(matches(isDisplayed()))
}
}The project uses Kotest for property-based tests (e.g., MessageAdapterPropertyTest.kt):
import io.kotest.core.spec.style.FunSpec
import io.kotest.property.forAll
import io.kotest.property.Arb
import io.kotest.property.arbitrary.string
class BubbleFactoryTest : FunSpec({
// NOTE: BubbleFactory has NO public getKey(category, type) helper — a factory
// is matched purely by the getCategory()/getType() pair it overrides. Test that
// your custom factory reports the category/type it intends to handle.
test("custom BubbleFactory reports its target category and type") {
val factory = MyPollBubbleFactory() // your BubbleFactory subclass
factory.getCategory() shouldBe "custom"
factory.getType() shouldBe "extension_poll"
}
})The master-app-jetpack/ai-testing/ directory contains Maestro test configurations:
# maestro/login_flow.yaml
appId: com.example.jetpackuikit
---
- launchApp
- tapOn: "Login"
- inputText: "superhero1"
- tapOn: "Submit"
- assertVisible: "Chats"Run with:
maestro test maestro/login_flow.yamlname: Test
on: [push, pull_request]
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- run: ./gradlew testDebugUnitTest
instrumented-tests:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 34
script: ./gradlew connectedDebugAndroidTest| Test Type | Location | Framework | What to Test |
|---|---|---|---|
| Unit tests | chatuikit-core/src/test/ | JUnit + Kotest + Mockito | ViewModels, DataSources, Repositories, Events |
| Unit tests | chatuikit-compose/src/test/ | JUnit + Kotest | BubbleFactory, style resolution |
| Compose UI tests | chatuikit-compose/src/androidTest/ | Compose Test | Component rendering, interactions |
| Views UI tests | chatuikit-kotlin/src/androidTest/ | Espresso | Component rendering, interactions |
| E2E tests | master-app-*/ai-testing/ | Maestro | Full user flows |
CometChatTheme {} wrapper in Compose test setContent blocks — components depend on CompositionLocal valuesrunTest from kotlinx-coroutines-test for testing coroutines and SharedFlowuseJUnitPlatform() in test options for Kotest compatibilitycreateComposeRule() not createAndroidComposeRule() unless you need Activity context~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.