Skip to content

Commit 6c55f3c

Browse files
authored
Added unit tests (#7)
* unit testing * Create ci.yml
1 parent f81fe44 commit 6c55f3c

File tree

10 files changed

+564
-34
lines changed

10 files changed

+564
-34
lines changed

.github/workflows/ci.yml

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
name: Android CI
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
push:
7+
branches: [ main ]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v2
16+
17+
- name: Set up JDK 17
18+
uses: actions/setup-java@v1
19+
with:
20+
java-version: 17
21+
22+
- name: Set up Android SDK
23+
uses: android-actions/setup-android@v2
24+
with:
25+
api-level: 30
26+
build-tools: 30.0.3
27+
28+
- name: Cache Gradle
29+
uses: actions/cache@v2
30+
with:
31+
path: |
32+
~/.gradle/caches
33+
~/.gradle/wrapper
34+
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
35+
restore-keys: |
36+
${{ runner.os }}-gradle-
37+
38+
- name: Build with Gradle (no tests)
39+
run: ./gradlew assemble
40+
41+
- name: Save Build Artifacts
42+
uses: actions/upload-artifact@v2
43+
with:
44+
name: app-build
45+
path: app/build/outputs/apk/
46+
47+
test:
48+
runs-on: ubuntu-latest
49+
needs: build
50+
51+
steps:
52+
- name: Checkout code
53+
uses: actions/checkout@v2
54+
55+
- name: Set up JDK 17
56+
uses: actions/setup-java@v1
57+
with:
58+
java-version: 17
59+
60+
- name: Set up Android SDK
61+
uses: android-actions/setup-android@v2
62+
with:
63+
api-level: 30
64+
build-tools: 30.0.3
65+
66+
- name: Cache Gradle
67+
uses: actions/cache@v2
68+
with:
69+
path: |
70+
~/.gradle/caches
71+
~/.gradle/wrapper
72+
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
73+
restore-keys: |
74+
${{ runner.os }}-gradle-
75+
76+
- name: Run Unit Tests and Capture Results
77+
id: run_tests
78+
run: |
79+
./gradlew test | tee test-results.txt
80+
TEST_RESULTS=$(grep -A 7 "Test Summary" test-results.txt | tail -n +2 | sed 's/\x1B\[[0-9;]*[JKmsu]//g' | tr -d '[:space:]')
81+
echo "$TEST_RESULTS" > test-summary.txt
82+
83+
# - name: Format Test Results for Two-Row Markdown Table with Emojis
84+
# run: |
85+
# echo "### Test Results" > formatted-summary.txt
86+
# echo "" >> formatted-summary.txt
87+
# echo "| Total Tests | Passed | Failed | Skipped | Result |" >> formatted-summary.txt
88+
# echo "|-------------|--------|--------|---------|--------|" >> formatted-summary.txt
89+
90+
# echo "Raw Test Summary Content:"
91+
# cat test-summary.txt
92+
93+
# # Extracting values using awk
94+
# TOTAL=$(echo "$TEST_RESULTS" | awk -F'[: ]+' '/TotalTests/ {print $2}')
95+
# PASSED=$(echo "$TEST_RESULTS" | awk -F'[: ]+' '/Passed/ {print $2}')
96+
# FAILED=$(echo "$TEST_RESULTS" | awk -F'[: ]+' '/Failed/ {print $2}')
97+
# SKIPPED=$(echo "$TEST_RESULTS" | awk -F'[: ]+' '/Skipped/ {print $2}')
98+
# RESULT=$(echo "$TEST_RESULTS" | awk -F'[: ]+' '/Result/ {print $2}')
99+
100+
# # Detailed debugging
101+
# echo "Debug: Extracted Values:"
102+
# echo " TOTAL: '$TOTAL'"
103+
# echo " PASSED: '$PASSED'"
104+
# echo " FAILED: '$FAILED'"
105+
# echo " SKIPPED: '$SKIPPED'"
106+
# echo " RESULT (Raw): '$RESULT'"
107+
108+
# if [[ "$RESULT" == "SUCCESS" ]]; then
109+
# EMOJI="✅"
110+
# elif [[ "$RESULT" == "FAILURE" ]]; then
111+
# EMOJI="❌"
112+
# else
113+
# EMOJI="⚠️"
114+
# fi
115+
116+
# echo "Debug: Final RESULT after processing: '$RESULT $EMOJI'"
117+
118+
# echo "| $TOTAL | $PASSED | $FAILED | $SKIPPED | $RESULT $EMOJI |" >> formatted-summary.txt
119+
120+
# # Show the final output for debugging
121+
# echo "Final formatted-summary.txt content:"
122+
# cat formatted-summary.txt
123+
124+
# - name: Comment on PR
125+
# if: github.event_name == 'pull_request'
126+
# uses: actions/github-script@v6
127+
# with:
128+
# script: |
129+
# const fs = require('fs');
130+
# const testResults = fs.readFileSync('formatted-summary.txt', 'utf8');
131+
# github.rest.issues.createComment({
132+
# issue_number: context.issue.number,
133+
# owner: context.repo.owner,
134+
# repo: context.repo.repo,
135+
# body: testResults
136+
# });

chat-sdk/build.gradle.kts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,7 @@ dependencies {
6464
implementation(libs.composeUiGraphics)
6565
implementation(libs.composeUiToolingPreview)
6666
implementation(libs.material3)
67-
implementation("com.google.android.gms:play-services-basement:18.2.0")
6867
implementation(libs.runtimeLivedata)
69-
implementation(libs.lifecycleProcess) // Add this dependency in libs.versions.toml if necessary
70-
testImplementation(libs.junit)
71-
androidTestImplementation(libs.androidxJunit)
72-
androidTestImplementation(libs.espressoCore)
73-
androidTestImplementation(platform(libs.composeBom))
74-
androidTestImplementation(libs.composeUiTestJunit4)
75-
debugImplementation(libs.composeUiTooling)
76-
debugImplementation(libs.composeUiTestManifest)
7768

7869
// Lifecycle livedata
7970
implementation(libs.lifecycleLivedataKtx)
@@ -91,6 +82,7 @@ dependencies {
9182
//Hilt
9283
implementation(libs.hiltAndroid)
9384
implementation(libs.hiltNavigationCompose)
85+
implementation(libs.lifecycleProcess)
9486
kapt(libs.hiltCompiler)
9587
implementation(libs.navigationCompose)
9688
kapt(libs.hiltAndroidCompiler)
@@ -105,6 +97,24 @@ dependencies {
10597
// Image loading
10698
implementation(libs.coilCompose)
10799

100+
// Testing
101+
// Mockito for mocking
102+
testImplementation(libs.mockito.core)
103+
testImplementation(libs.mockito.inline)
104+
105+
// Kotlin extensions for Mockito
106+
testImplementation(libs.mockito.kotlin)
107+
108+
// Coroutines test library
109+
testImplementation(libs.coroutines.test)
110+
111+
testImplementation(libs.junit)
112+
androidTestImplementation(libs.androidxJunit)
113+
androidTestImplementation(platform(libs.composeBom))
114+
androidTestImplementation(libs.composeUiTestJunit4)
115+
debugImplementation(libs.composeUiTooling)
116+
debugImplementation(libs.composeUiTestManifest)
117+
testImplementation(libs.robolectric)
108118
}
109119

110120
publishing {
@@ -129,3 +139,6 @@ publishing {
129139
tasks.withType<AbstractPublishToMaven>().configureEach {
130140
dependsOn(tasks.named("assembleRelease"))
131141
}
142+
143+
// Test summary gradle file
144+
apply(from = "test-summary.gradle.kts")

chat-sdk/src/main/java/com/amazon/connect/chat/sdk/network/WebSocketManager.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,24 @@ import android.net.Network
55
import android.util.Log
66
import androidx.lifecycle.Lifecycle
77
import androidx.lifecycle.LifecycleEventObserver
8-
import androidx.lifecycle.LifecycleObserver
98
import androidx.lifecycle.ProcessLifecycleOwner
109
import com.amazon.connect.chat.sdk.Config
1110
import com.amazon.connect.chat.sdk.model.Message
1211
import com.amazon.connect.chat.sdk.model.MessageType
1312
import com.amazon.connect.chat.sdk.model.TranscriptItem
1413
import com.amazon.connect.chat.sdk.utils.CommonUtils
1514
import com.amazon.connect.chat.sdk.utils.ContentType
15+
import kotlinx.coroutines.CoroutineScope
16+
import kotlinx.coroutines.Dispatchers
17+
import kotlinx.coroutines.launch
1618
import okhttp3.OkHttpClient
1719
import okhttp3.Request
1820
import okhttp3.Response
1921
import okhttp3.WebSocket
2022
import okhttp3.WebSocketListener
21-
import java.util.concurrent.TimeUnit
22-
import kotlinx.coroutines.CoroutineScope
23-
import kotlinx.coroutines.Dispatchers
24-
import kotlinx.coroutines.launch
2523
import okio.IOException
2624
import org.json.JSONObject
25+
import java.util.concurrent.TimeUnit
2726
import javax.inject.Inject
2827

2928
object EventTypes {

chat-sdk/src/main/java/com/amazon/connect/chat/sdk/repository/ChatService.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ interface ChatService {
2020
* Disconnects the current chat session.
2121
* @return A Result indicating whether the disconnection was successful.
2222
*/
23-
suspend fun disconnectChatSession(): Result<Unit>
23+
suspend fun disconnectChatSession(): Result<Boolean>
2424
}
2525

2626
class ChatServiceImpl @Inject constructor(
@@ -44,13 +44,13 @@ class ChatServiceImpl @Inject constructor(
4444
}
4545
}
4646

47-
override suspend fun disconnectChatSession(): Result<Unit> {
47+
override suspend fun disconnectChatSession(): Result<Boolean> {
4848
return runCatching {
4949
val connectionDetails = connectionDetailsProvider.getConnectionDetails()
5050
?: throw Exception("No connection details available")
5151
awsClient.disconnectParticipantConnection(connectionDetails.connectionToken).getOrThrow()
5252
Log.d("ChatServiceImpl", "Participant Disconnected")
53-
Unit
53+
true
5454
}.onFailure { exception ->
5555
Log.e("ChatServiceImpl", "Failed to disconnect participant: ${exception.message}", exception)
5656
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.amazon.connect.chat.sdk
2+
3+
import com.amazon.connect.chat.sdk.model.ChatDetails
4+
import com.amazon.connect.chat.sdk.model.GlobalConfig
5+
import com.amazon.connect.chat.sdk.repository.ChatService
6+
import com.amazonaws.regions.Regions
7+
import junit.framework.TestCase.assertTrue
8+
import kotlinx.coroutines.ExperimentalCoroutinesApi
9+
import kotlinx.coroutines.test.runTest
10+
import org.junit.Before
11+
import org.junit.Test
12+
import org.junit.runner.RunWith
13+
import org.mockito.Mock
14+
import org.mockito.Mockito.*
15+
import org.mockito.MockitoAnnotations
16+
import org.mockito.kotlin.verify
17+
import org.robolectric.RobolectricTestRunner
18+
19+
20+
@ExperimentalCoroutinesApi
21+
@RunWith(RobolectricTestRunner::class)
22+
class ChatSessionImplTest {
23+
24+
@Mock
25+
private lateinit var chatService: ChatService
26+
27+
private lateinit var chatSession: ChatSession
28+
29+
@Before
30+
fun setUp() {
31+
MockitoAnnotations.openMocks(this)
32+
chatSession = ChatSessionImpl(chatService)
33+
}
34+
35+
@Test
36+
fun test_configure(){
37+
val config = GlobalConfig(region = Regions.US_WEST_2)
38+
chatSession.configure(config)
39+
verify(chatService).configure(config)
40+
}
41+
42+
@Test
43+
fun test_connect_success() = runTest {
44+
val chatDetails = ChatDetails(participantToken = "participant-token")
45+
`when`(chatService.createChatSession(chatDetails)).thenReturn(Result.success(true))
46+
47+
val result = chatSession.connect(chatDetails)
48+
49+
assertTrue(result.isSuccess)
50+
verify(chatService).createChatSession(chatDetails)
51+
}
52+
53+
@Test
54+
fun test_connect_failure() = runTest {
55+
val chatDetails = ChatDetails(participantToken = "invalid token")
56+
`when`(chatService.createChatSession(chatDetails)).thenThrow(RuntimeException("Network error"))
57+
58+
val result = chatSession.connect(chatDetails)
59+
60+
assertTrue(result.isFailure)
61+
verify(chatService).createChatSession(chatDetails)
62+
}
63+
64+
@Test
65+
fun test_disconnect_success() = runTest {
66+
`when`(chatService.disconnectChatSession()).thenReturn(Result.success(true))
67+
68+
val result = chatSession.disconnect()
69+
70+
assertTrue(result.isSuccess)
71+
verify(chatService).disconnectChatSession()
72+
}
73+
74+
@Test
75+
fun test_disconnect_failure() = runTest {
76+
`when`(chatService.disconnectChatSession()).thenThrow(RuntimeException("Network error"))
77+
78+
val result = chatSession.disconnect()
79+
80+
assertTrue(result.isFailure)
81+
verify(chatService).disconnectChatSession()
82+
}
83+
84+
}

chat-sdk/src/test/java/com/amazon/connect/chat/sdk/ExampleUnitTest.kt

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)